1/*	$OpenBSD: privsep.c,v 1.79 2020/11/21 18:34:25 krw Exp $ */
2
3/*
4 * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
15 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/queue.h>
20#include <sys/socket.h>
21
22#include <net/if.h>
23#include <net/route.h>
24
25#include <netinet/in.h>
26#include <netinet/if_ether.h>
27
28#include <errno.h>
29#include <imsg.h>
30#include <resolv.h>
31#include <signal.h>
32#include <stdio.h>
33#include <stdint.h>
34#include <stdlib.h>
35#include <string.h>
36
37#include "dhcp.h"
38#include "dhcpd.h"
39#include "log.h"
40#include "privsep.h"
41
42void
43dispatch_imsg(char *name, int rdomain, int ioctlfd, int routefd,
44    struct imsgbuf *ibuf)
45{
46	static char	*resolv_conf;
47	static int	 lastidx;
48	struct imsg	 imsg;
49	ssize_t		 n;
50	int		 index;
51
52	index = if_nametoindex(name);
53	if (index == 0) {
54		log_warnx("%s: unknown interface", log_procname);
55		quit = TERMINATE;
56		return;
57	}
58
59	for (;;) {
60		if ((n = imsg_get(ibuf, &imsg)) == -1)
61			fatal("imsg_get");
62
63		if (n == 0)
64			break;
65
66		switch (imsg.hdr.type) {
67		case IMSG_REVOKE:
68			if (imsg.hdr.len != IMSG_HEADER_SIZE +
69			    sizeof(struct proposal))
70				log_warnx("%s: bad IMSG_REVOKE",
71				    log_procname);
72			else
73				priv_revoke_proposal(name, ioctlfd, imsg.data,
74				    &resolv_conf);
75			break;
76
77		case IMSG_PROPOSE:
78			if (imsg.hdr.len < IMSG_HEADER_SIZE +
79			    sizeof(struct proposal))
80				log_warnx("%s: bad IMSG_PROPOSE",
81				    log_procname);
82			else {
83				priv_propose(name, ioctlfd, imsg.data,
84				    imsg.hdr.len - IMSG_HEADER_SIZE - sizeof(struct proposal),
85				    &resolv_conf, routefd, rdomain, index, &lastidx);
86			}
87			break;
88
89		case IMSG_WRITE_RESOLV_CONF:
90			if (imsg.hdr.len != IMSG_HEADER_SIZE)
91				log_warnx("%s: bad IMSG_WRITE_RESOLV_CONF",
92				    log_procname);
93			else
94				priv_write_resolv_conf(index, routefd, rdomain,
95				    resolv_conf, &lastidx);
96			break;
97
98		case IMSG_TELL_UNWIND:
99			if (imsg.hdr.len != IMSG_HEADER_SIZE +
100			    sizeof(struct unwind_info))
101				log_warnx("%s: bad IMSG_TELL_UNWIND",
102				    log_procname);
103			else
104				priv_tell_unwind(index, routefd, rdomain, imsg.data);
105			break;
106
107		default:
108			log_warnx("%s: received unknown message, code %u",
109			    log_procname, imsg.hdr.type);
110		}
111
112		imsg_free(&imsg);
113	}
114}
115