control.c revision 301803
1215976Sjmallett/*-
2232812Sjmallett * Copyright (C) 2011 Hiroki Sato <hrs@FreeBSD.org>
3215976Sjmallett * All rights reserved.
4215976Sjmallett *
5215976Sjmallett * Redistribution and use in source and binary forms, with or without
6215976Sjmallett * modification, are permitted provided that the following conditions
7215976Sjmallett * are met:
8215976Sjmallett * 1. Redistributions of source code must retain the above copyright
9215976Sjmallett *    notice, this list of conditions and the following disclaimer.
10215976Sjmallett * 2. Redistributions in binary form must reproduce the above copyright
11215976Sjmallett *    notice, this list of conditions and the following disclaimer in the
12215976Sjmallett *    documentation and/or other materials provided with the distribution.
13215976Sjmallett *
14215976Sjmallett * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
15215976Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16215976Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17215976Sjmallett * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS
18232812Sjmallett * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19215976Sjmallett * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20215976Sjmallett * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
21215976Sjmallett * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22215976Sjmallett * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23215976Sjmallett * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24215976Sjmallett * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25215976Sjmallett *
26215976Sjmallett * $FreeBSD: stable/10/usr.sbin/rtadvd/control.c 301803 2016-06-10 18:02:51Z ngie $
27215976Sjmallett *
28215976Sjmallett */
29232812Sjmallett
30215976Sjmallett#include <sys/queue.h>
31215976Sjmallett#include <sys/types.h>
32215976Sjmallett#include <sys/socket.h>
33215976Sjmallett#include <sys/stat.h>
34215976Sjmallett#include <sys/un.h>
35215976Sjmallett#include <sys/uio.h>
36215976Sjmallett#include <net/if.h>
37215976Sjmallett#include <net/if_dl.h>
38215976Sjmallett#include <netinet/in.h>
39215976Sjmallett#include <netinet/icmp6.h>
40215976Sjmallett#include <fcntl.h>
41215976Sjmallett#include <errno.h>
42215976Sjmallett#include <netdb.h>
43215976Sjmallett#include <unistd.h>
44215976Sjmallett#include <poll.h>
45215976Sjmallett#include <signal.h>
46215976Sjmallett#include <string.h>
47215976Sjmallett#include <stdarg.h>
48215976Sjmallett#include <stdio.h>
49215976Sjmallett#include <stdlib.h>
50215976Sjmallett#include <syslog.h>
51215976Sjmallett
52232812Sjmallett#include "rtadvd.h"
53232812Sjmallett#include "if.h"
54215976Sjmallett#include "pathnames.h"
55215976Sjmallett#include "control.h"
56215976Sjmallett
57215976Sjmallett#define	CM_RECV_TIMEOUT	30
58215976Sjmallett
59215976Sjmallettint
60215976Sjmallettcm_recv(int fd, char *buf)
61215976Sjmallett{
62215976Sjmallett	ssize_t n;
63215976Sjmallett	struct ctrl_msg_hdr	*cm;
64215976Sjmallett	char *msg;
65215976Sjmallett	struct pollfd pfds[1];
66215976Sjmallett	int i;
67215976Sjmallett
68215976Sjmallett	syslog(LOG_DEBUG, "<%s> enter, fd=%d", __func__, fd);
69215976Sjmallett
70215976Sjmallett	memset(buf, 0, CM_MSG_MAXLEN);
71215976Sjmallett	cm = (struct ctrl_msg_hdr *)buf;
72215976Sjmallett	msg = (char *)buf + sizeof(*cm);
73215976Sjmallett
74215976Sjmallett	pfds[0].fd = fd;
75215976Sjmallett	pfds[0].events = POLLIN;
76215976Sjmallett
77215976Sjmallett	for (;;) {
78215976Sjmallett		i = poll(pfds, sizeof(pfds)/sizeof(pfds[0]),
79215976Sjmallett		    CM_RECV_TIMEOUT);
80215976Sjmallett
81215976Sjmallett		if (i == 0)
82215976Sjmallett			continue;
83215976Sjmallett
84215976Sjmallett		if (i < 0) {
85215976Sjmallett			syslog(LOG_ERR, "<%s> poll error: %s",
86215976Sjmallett			    __func__, strerror(errno));
87215976Sjmallett			continue;
88215976Sjmallett		}
89215976Sjmallett
90215976Sjmallett		if (pfds[0].revents & POLLIN) {
91215976Sjmallett			n = read(fd, cm, sizeof(*cm));
92215976Sjmallett			if (n < 0 && errno == EAGAIN) {
93215976Sjmallett				syslog(LOG_DEBUG,
94215976Sjmallett				    "<%s> waiting...", __func__);
95215976Sjmallett				continue;
96215976Sjmallett			}
97215976Sjmallett			break;
98215976Sjmallett		}
99215976Sjmallett	}
100215976Sjmallett
101215976Sjmallett	if (n != (ssize_t)sizeof(*cm)) {
102215976Sjmallett		syslog(LOG_WARNING,
103215976Sjmallett		    "<%s> received a too small message.", __func__);
104215976Sjmallett		goto cm_recv_err;
105215976Sjmallett	}
106215976Sjmallett	if (cm->cm_len > CM_MSG_MAXLEN) {
107215976Sjmallett		syslog(LOG_WARNING,
108215976Sjmallett		    "<%s> received a too large message.", __func__);
109215976Sjmallett		goto cm_recv_err;
110215976Sjmallett	}
111215976Sjmallett	if (cm->cm_version != CM_VERSION) {
112215976Sjmallett		syslog(LOG_WARNING,
113215976Sjmallett		    "<%s> version mismatch", __func__);
114215976Sjmallett		goto cm_recv_err;
115215976Sjmallett	}
116215976Sjmallett	if (cm->cm_type >= CM_TYPE_MAX) {
117215976Sjmallett		syslog(LOG_WARNING,
118215976Sjmallett		    "<%s> invalid msg type.", __func__);
119215976Sjmallett		goto cm_recv_err;
120215976Sjmallett	}
121215976Sjmallett
122215976Sjmallett	syslog(LOG_DEBUG,
123215976Sjmallett	    "<%s> ctrl msg received: type=%d", __func__,
124215976Sjmallett	    cm->cm_type);
125215976Sjmallett
126215976Sjmallett	if (cm->cm_len > sizeof(*cm)) {
127215976Sjmallett		size_t msglen = cm->cm_len - sizeof(*cm);
128215976Sjmallett
129215976Sjmallett		syslog(LOG_DEBUG,
130215976Sjmallett		    "<%s> ctrl msg has payload (len=%zu)", __func__,
131215976Sjmallett		    msglen);
132215976Sjmallett
133215976Sjmallett		for (;;) {
134215976Sjmallett			i = poll(pfds, sizeof(pfds)/sizeof(pfds[0]),
135215976Sjmallett			    CM_RECV_TIMEOUT);
136215976Sjmallett
137215976Sjmallett			if (i == 0)
138215976Sjmallett				continue;
139215976Sjmallett
140215976Sjmallett			if (i < 0) {
141215976Sjmallett				syslog(LOG_ERR, "<%s> poll error: %s",
142215976Sjmallett				    __func__, strerror(errno));
143215976Sjmallett				continue;
144215976Sjmallett			}
145215976Sjmallett
146215976Sjmallett			if (pfds[0].revents & POLLIN) {
147215976Sjmallett				n = read(fd, msg, msglen);
148215976Sjmallett				if (n < 0 && errno == EAGAIN) {
149215976Sjmallett					syslog(LOG_DEBUG,
150215976Sjmallett					    "<%s> waiting...", __func__);
151215976Sjmallett					continue;
152215976Sjmallett				}
153215976Sjmallett			}
154215976Sjmallett			break;
155215976Sjmallett		}
156215976Sjmallett		if (n != (ssize_t)msglen) {
157215976Sjmallett			syslog(LOG_WARNING,
158215976Sjmallett			    "<%s> payload size mismatch.", __func__);
159215976Sjmallett			goto cm_recv_err;
160215976Sjmallett		}
161215976Sjmallett		buf[CM_MSG_MAXLEN - 1] = '\0';
162215976Sjmallett	}
163215976Sjmallett
164215976Sjmallett	return (0);
165215976Sjmallett
166215976Sjmallettcm_recv_err:
167215976Sjmallett	close(fd);
168215976Sjmallett	return (-1);
169215976Sjmallett}
170215976Sjmallett
171215976Sjmallettint
172215976Sjmallettcm_send(int fd, char *buf)
173215976Sjmallett{
174215976Sjmallett	struct iovec iov[2];
175215976Sjmallett	int iovcnt;
176215976Sjmallett	ssize_t len;
177215976Sjmallett	ssize_t iov_len_total;
178215976Sjmallett	struct ctrl_msg_hdr *cm;
179215976Sjmallett	char *msg;
180215976Sjmallett
181215976Sjmallett	cm = (struct ctrl_msg_hdr *)buf;
182215976Sjmallett	msg = (char *)buf + sizeof(*cm);
183215976Sjmallett
184215976Sjmallett	iovcnt = 1;
185215976Sjmallett	iov[0].iov_base = cm;
186215976Sjmallett	iov[0].iov_len = sizeof(*cm);
187215976Sjmallett	iov_len_total = iov[0].iov_len;
188215976Sjmallett	if (cm->cm_len > sizeof(*cm)) {
189215976Sjmallett		iovcnt++;
190215976Sjmallett		iov[1].iov_base = msg;
191215976Sjmallett		iov[1].iov_len = cm->cm_len - iov[0].iov_len;
192215976Sjmallett		iov_len_total += iov[1].iov_len;
193215976Sjmallett	}
194215976Sjmallett
195215976Sjmallett	syslog(LOG_DEBUG,
196215976Sjmallett	    "<%s> ctrl msg send: type=%d, count=%d, total_len=%zd", __func__,
197215976Sjmallett	    cm->cm_type, iovcnt, iov_len_total);
198215976Sjmallett
199215976Sjmallett	len = writev(fd, iov, iovcnt);
200215976Sjmallett	syslog(LOG_DEBUG,
201215976Sjmallett	    "<%s> ctrl msg send: length=%zd", __func__, len);
202215976Sjmallett
203215976Sjmallett	if (len == -1) {
204215976Sjmallett		syslog(LOG_DEBUG,
205215976Sjmallett		    "<%s> write failed: (%d)%s", __func__, errno,
206215976Sjmallett		    strerror(errno));
207215976Sjmallett		close(fd);
208215976Sjmallett		return (-1);
209215976Sjmallett	}
210215976Sjmallett
211215976Sjmallett	syslog(LOG_DEBUG,
212215976Sjmallett	    "<%s> write length = %zd (actual)", __func__, len);
213215976Sjmallett	syslog(LOG_DEBUG,
214215976Sjmallett	    "<%s> write length = %zd (expected)", __func__, iov_len_total);
215215976Sjmallett
216215976Sjmallett	if (len != iov_len_total) {
217215976Sjmallett		close(fd);
218215976Sjmallett		return (-1);
219215976Sjmallett	}
220215976Sjmallett
221215976Sjmallett	return (0);
222215976Sjmallett}
223215976Sjmallett
224215976Sjmallettint
225215976Sjmallettcsock_accept(struct sockinfo *s)
226215976Sjmallett{
227215976Sjmallett	struct sockaddr_un	sun;
228215976Sjmallett	int	flags;
229215976Sjmallett	int	fd;
230215976Sjmallett
231215976Sjmallett	sun.sun_len = sizeof(sun);
232215976Sjmallett	if ((fd = accept(s->si_fd, (struct sockaddr *)&sun,
233215976Sjmallett		    (socklen_t *)&sun.sun_len)) == -1) {
234215976Sjmallett		if (errno != EWOULDBLOCK && errno != EINTR)
235215976Sjmallett			syslog(LOG_WARNING, "<%s> accept ", __func__);
236215976Sjmallett		syslog(LOG_WARNING, "<%s> Xaccept: %s", __func__, strerror(errno));
237215976Sjmallett		return (-1);
238215976Sjmallett	}
239215976Sjmallett	if ((flags = fcntl(fd, F_GETFL, 0)) == -1) {
240215976Sjmallett		syslog(LOG_WARNING, "<%s> fcntl F_GETFL", __func__);
241215976Sjmallett		close(s->si_fd);
242215976Sjmallett		return (-1);
243215976Sjmallett	}
244215976Sjmallett	if ((flags = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1) {
245215976Sjmallett		syslog(LOG_WARNING, "<%s> fcntl F_SETFL", __func__);
246215976Sjmallett		return (-1);
247215976Sjmallett	}
248215976Sjmallett	syslog(LOG_DEBUG, "<%s> accept connfd=%d, listenfd=%d", __func__,
249215976Sjmallett	    fd, s->si_fd);
250215976Sjmallett
251215976Sjmallett	return (fd);
252215976Sjmallett}
253215976Sjmallett
254215976Sjmallettint
255215976Sjmallettcsock_close(struct sockinfo *s)
256215976Sjmallett{
257215976Sjmallett	close(s->si_fd);
258215976Sjmallett	unlink(s->si_name);
259215976Sjmallett	syslog(LOG_DEBUG, "<%s> remove %s", __func__, s->si_name);
260215976Sjmallett	return (0);
261215976Sjmallett}
262215976Sjmallett
263215976Sjmallettint
264215976Sjmallettcsock_listen(struct sockinfo *s)
265215976Sjmallett{
266215976Sjmallett	if (s->si_fd == -1) {
267215976Sjmallett		syslog(LOG_ERR, "<%s> listen failed", __func__);
268215976Sjmallett		return (-1);
269215976Sjmallett	}
270215976Sjmallett	if (listen(s->si_fd, SOCK_BACKLOG) == -1) {
271215976Sjmallett		syslog(LOG_ERR, "<%s> listen failed", __func__);
272215976Sjmallett		return (-1);
273215976Sjmallett	}
274215976Sjmallett
275215976Sjmallett	return (0);
276215976Sjmallett}
277215976Sjmallett
278215976Sjmallettint
279215976Sjmallettcsock_open(struct sockinfo *s, mode_t mode)
280215976Sjmallett{
281215976Sjmallett	int flags;
282215976Sjmallett	struct sockaddr_un	sun;
283215976Sjmallett	mode_t	old_umask;
284215976Sjmallett
285215976Sjmallett	if (s == NULL) {
286215976Sjmallett		syslog(LOG_ERR, "<%s> internal error.", __func__);
287215976Sjmallett		exit(1);
288215976Sjmallett	}
289215976Sjmallett	if (s->si_name == NULL)
290215976Sjmallett		s->si_name = _PATH_CTRL_SOCK;
291215976Sjmallett
292215976Sjmallett	if ((s->si_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
293215976Sjmallett		syslog(LOG_ERR,
294215976Sjmallett		    "<%s> cannot open control socket", __func__);
295215976Sjmallett		return (-1);
296215976Sjmallett	}
297215976Sjmallett	memset(&sun, 0, sizeof(sun));
298215976Sjmallett	sun.sun_family = AF_UNIX;
299215976Sjmallett	sun.sun_len = sizeof(sun);
300215976Sjmallett	strlcpy(sun.sun_path, s->si_name, sizeof(sun.sun_path));
301215976Sjmallett
302215976Sjmallett	if (unlink(s->si_name) == -1)
303215976Sjmallett		if (errno != ENOENT) {
304215976Sjmallett			syslog(LOG_ERR,
305215976Sjmallett			    "<%s> unlink %s", __func__, s->si_name);
306215976Sjmallett			close(s->si_fd);
307215976Sjmallett			return (-1);
308215976Sjmallett		}
309215976Sjmallett	old_umask = umask(S_IXUSR|S_IXGRP|S_IXOTH);
310215976Sjmallett	if (bind(s->si_fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
311215976Sjmallett		syslog(LOG_ERR,
312215976Sjmallett		    "<%s> bind failed: %s", __func__, s->si_name);
313215976Sjmallett		close(s->si_fd);
314215976Sjmallett		umask(old_umask);
315215976Sjmallett		return (-1);
316215976Sjmallett	}
317215976Sjmallett	umask(old_umask);
318215976Sjmallett	if (chmod(s->si_name, mode) == -1) {
319215976Sjmallett		syslog(LOG_ERR,
320215976Sjmallett		    "<%s> chmod failed: %s", __func__, s->si_name);
321215976Sjmallett		goto csock_open_err;
322215976Sjmallett	}
323215976Sjmallett	if ((flags = fcntl(s->si_fd, F_GETFL, 0)) == -1) {
324215976Sjmallett		syslog(LOG_ERR,
325215976Sjmallett		    "<%s> fcntl F_GETFL failed: %s", __func__, s->si_name);
326215976Sjmallett		goto csock_open_err;
327215976Sjmallett	}
328215976Sjmallett	if ((flags = fcntl(s->si_fd, F_SETFL, flags | O_NONBLOCK)) == -1) {
329215976Sjmallett		syslog(LOG_ERR,
330215976Sjmallett		    "<%s> fcntl F_SETFL failed: %s", __func__, s->si_name);
331215976Sjmallett		goto csock_open_err;
332215976Sjmallett	}
333215976Sjmallett
334215976Sjmallett	return (s->si_fd);
335215976Sjmallett
336215976Sjmallettcsock_open_err:
337215976Sjmallett	close(s->si_fd);
338215976Sjmallett	unlink(s->si_name);
339215976Sjmallett	return (-1);
340215976Sjmallett}
341215976Sjmallett
342215976Sjmallettstruct ctrl_msg_pl *
343215976Sjmallettcm_bin2pl(char *str, struct ctrl_msg_pl *cp)
344215976Sjmallett{
345215976Sjmallett	size_t len;
346215976Sjmallett	size_t *lenp;
347215976Sjmallett	char *p;
348215976Sjmallett
349215976Sjmallett	memset(cp, 0, sizeof(*cp));
350215976Sjmallett
351215976Sjmallett	p = str;
352215976Sjmallett
353215976Sjmallett	lenp = (size_t *)p;
354215976Sjmallett	len = *lenp++;
355215976Sjmallett	p = (char *)lenp;
356215976Sjmallett	syslog(LOG_DEBUG, "<%s> len(ifname) = %zu", __func__, len);
357215976Sjmallett	if (len > 0) {
358215976Sjmallett		cp->cp_ifname = malloc(len + 1);
359215976Sjmallett		if (cp->cp_ifname == NULL) {
360215976Sjmallett			syslog(LOG_ERR, "<%s> malloc", __func__);
361215976Sjmallett			exit(1);
362215976Sjmallett		}
363215976Sjmallett		memcpy(cp->cp_ifname, p, len);
364215976Sjmallett		cp->cp_ifname[len] = '\0';
365215976Sjmallett		p += len;
366215976Sjmallett	}
367215976Sjmallett
368215976Sjmallett	lenp = (size_t *)p;
369215976Sjmallett	len = *lenp++;
370215976Sjmallett	p = (char *)lenp;
371215976Sjmallett	syslog(LOG_DEBUG, "<%s> len(key) = %zu", __func__, len);
372215976Sjmallett	if (len > 0) {
373215976Sjmallett		cp->cp_key = malloc(len + 1);
374215976Sjmallett		if (cp->cp_key == NULL) {
375215976Sjmallett			syslog(LOG_ERR, "<%s> malloc", __func__);
376215976Sjmallett			exit(1);
377215976Sjmallett		}
378215976Sjmallett		memcpy(cp->cp_key, p, len);
379215976Sjmallett		cp->cp_key[len] = '\0';
380215976Sjmallett		p += len;
381215976Sjmallett	}
382215976Sjmallett
383215976Sjmallett	lenp = (size_t *)p;
384215976Sjmallett	len = *lenp++;
385215976Sjmallett	p = (char *)lenp;
386215976Sjmallett	syslog(LOG_DEBUG, "<%s> len(val) = %zu", __func__, len);
387215976Sjmallett	if (len > 0) {
388215976Sjmallett		cp->cp_val = malloc(len + 1);
389215976Sjmallett		if (cp->cp_val == NULL) {
390215976Sjmallett			syslog(LOG_ERR, "<%s> malloc", __func__);
391215976Sjmallett			exit(1);
392215976Sjmallett		}
393215976Sjmallett		memcpy(cp->cp_val, p, len);
394215976Sjmallett		cp->cp_val[len] = '\0';
395215976Sjmallett		cp->cp_val_len = len;
396215976Sjmallett	} else
397215976Sjmallett		cp->cp_val_len = 0;
398215976Sjmallett
399215976Sjmallett	return (cp);
400215976Sjmallett}
401215976Sjmallett
402215976Sjmallettsize_t
403215976Sjmallettcm_pl2bin(char *str, struct ctrl_msg_pl *cp)
404215976Sjmallett{
405215976Sjmallett	size_t len;
406215976Sjmallett	size_t *lenp;
407215976Sjmallett	char *p;
408215976Sjmallett	struct ctrl_msg_hdr *cm;
409215976Sjmallett
410215976Sjmallett	len = sizeof(size_t);
411215976Sjmallett	if (cp->cp_ifname != NULL)
412215976Sjmallett		len += strlen(cp->cp_ifname);
413215976Sjmallett	len += sizeof(size_t);
414215976Sjmallett	if (cp->cp_key != NULL)
415215976Sjmallett		len += strlen(cp->cp_key);
416215976Sjmallett	len += sizeof(size_t);
417215976Sjmallett	if (cp->cp_val != NULL && cp->cp_val_len > 0)
418215976Sjmallett		len += cp->cp_val_len;
419215976Sjmallett
420215976Sjmallett	if (len > CM_MSG_MAXLEN - sizeof(*cm)) {
421215976Sjmallett		syslog(LOG_DEBUG, "<%s> msg too long (len=%zu)",
422215976Sjmallett		    __func__, len);
423215976Sjmallett		return (0);
424215976Sjmallett	}
425215976Sjmallett	syslog(LOG_DEBUG, "<%s> msglen=%zu", __func__, len);
426215976Sjmallett	memset(str, 0, len);
427215976Sjmallett	p = str;
428215976Sjmallett	lenp = (size_t *)p;
429215976Sjmallett
430215976Sjmallett	if (cp->cp_ifname != NULL) {
431215976Sjmallett		*lenp++ = strlen(cp->cp_ifname);
432215976Sjmallett		p = (char *)lenp;
433215976Sjmallett		memcpy(p, cp->cp_ifname, strlen(cp->cp_ifname));
434215976Sjmallett		p += strlen(cp->cp_ifname);
435215976Sjmallett	} else {
436215976Sjmallett		*lenp++ = '\0';
437215976Sjmallett		p = (char *)lenp;
438215976Sjmallett	}
439215976Sjmallett
440215976Sjmallett	lenp = (size_t *)p;
441215976Sjmallett	if (cp->cp_key != NULL) {
442215976Sjmallett		*lenp++ = strlen(cp->cp_key);
443215976Sjmallett		p = (char *)lenp;
444215976Sjmallett		memcpy(p, cp->cp_key, strlen(cp->cp_key));
445215976Sjmallett		p += strlen(cp->cp_key);
446215976Sjmallett	} else {
447215976Sjmallett		*lenp++ = '\0';
448215976Sjmallett		p = (char *)lenp;
449215976Sjmallett	}
450215976Sjmallett
451215976Sjmallett	lenp = (size_t *)p;
452215976Sjmallett	if (cp->cp_val != NULL && cp->cp_val_len > 0) {
453215976Sjmallett		*lenp++ = cp->cp_val_len;
454215976Sjmallett		p = (char *)lenp;
455215976Sjmallett		memcpy(p, cp->cp_val, cp->cp_val_len);
456215976Sjmallett		p += cp->cp_val_len;
457215976Sjmallett	} else {
458215976Sjmallett		*lenp++ = '\0';
459215976Sjmallett		p = (char *)lenp;
460215976Sjmallett	}
461215976Sjmallett
462215976Sjmallett	return (len);
463215976Sjmallett}
464215976Sjmallett
465215976Sjmallettsize_t
466215976Sjmallettcm_str2bin(char *bin, void *str, size_t len)
467215976Sjmallett{
468215976Sjmallett	struct ctrl_msg_hdr *cm;
469215976Sjmallett
470215976Sjmallett	syslog(LOG_DEBUG, "<%s> enter", __func__);
471215976Sjmallett
472215976Sjmallett	if (len > CM_MSG_MAXLEN - sizeof(*cm)) {
473215976Sjmallett		syslog(LOG_DEBUG, "<%s> msg too long (len=%zu)",
474215976Sjmallett		    __func__, len);
475215976Sjmallett		return (0);
476215976Sjmallett	}
477215976Sjmallett	syslog(LOG_DEBUG, "<%s> msglen=%zu", __func__, len);
478215976Sjmallett	memcpy(bin, (char *)str, len);
479215976Sjmallett
480215976Sjmallett	return (len);
481215976Sjmallett}
482215976Sjmallett
483215976Sjmallettvoid *
484215976Sjmallettcm_bin2str(char *bin, void *str, size_t len)
485215976Sjmallett{
486215976Sjmallett
487215976Sjmallett	syslog(LOG_DEBUG, "<%s> enter", __func__);
488215976Sjmallett
489215976Sjmallett	memcpy((char *)str, bin, len);
490215976Sjmallett
491215976Sjmallett	return (str);
492215976Sjmallett}
493215976Sjmallett