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