GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/dvmrpd/kmroute.c Lines: 0 96 0.0 %
Date: 2017-11-07 Branches: 0 34 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: kmroute.c,v 1.2 2010/05/26 13:56:07 nicm Exp $ */
2
3
/*
4
 * Copyright (c) 2005, 2006 Esben Norby <norby@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 USE, DATA OR PROFITS, WHETHER IN AN
15
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
#include <sys/socket.h>
21
#include <netinet/in.h>
22
#include <arpa/inet.h>
23
#include <netinet/ip_mroute.h>
24
25
#include <err.h>
26
#include <errno.h>
27
#include <stdlib.h>
28
#include <string.h>
29
30
#include "igmp.h"
31
#include "dvmrpd.h"
32
#include "dvmrp.h"
33
#include "dvmrpe.h"
34
#include "log.h"
35
36
extern struct dvmrpd_conf	*conf;
37
char				*mroute_ptr;	/* packet buffer */
38
39
void	main_imsg_compose_rde(int, pid_t, void *, u_int16_t);
40
41
int
42
kmr_init(int fd)
43
{
44
	struct iface		*iface;
45
	struct route_report	 rr;
46
47
	LIST_FOREACH(iface, &conf->iface_list, entry) {
48
		log_debug("kmr_init: interface %s", iface->name);
49
50
		rr.net.s_addr = iface->addr.s_addr & iface->mask.s_addr;
51
		rr.mask = iface->mask;
52
		rr.nexthop.s_addr = 0;
53
		rr.metric = iface->metric;
54
		rr.ifindex = iface->ifindex;
55
		main_imsg_compose_rde(IMSG_ROUTE_REPORT, -1, &rr, sizeof(rr));
56
57
		mrt_add_vif(conf->mroute_socket, iface);
58
	}
59
60
	if ((mroute_ptr = calloc(1, IBUF_READ_SIZE)) == NULL)
61
		fatal("kmr_init");
62
63
	return (0);
64
}
65
66
void
67
kmr_shutdown(void)
68
{
69
	struct iface		*iface;
70
71
	kmr_mfc_decouple();
72
	kmroute_clear();
73
74
	LIST_FOREACH(iface, &conf->iface_list, entry) {
75
		log_debug("kmr_shutdown: interface %s", iface->name);
76
77
		mrt_del_vif(conf->mroute_socket, iface);
78
	}
79
80
	free(mroute_ptr);
81
}
82
83
void
84
kmr_recv_msg(int fd, short event, void *bula)
85
{
86
	struct mfc		 mfc;
87
	struct igmpmsg		 kernel_msg;
88
	char			*buf;
89
	ssize_t			 r;
90
91
	if (event != EV_READ)
92
		return;
93
94
	/* setup buffer */
95
	buf = mroute_ptr;
96
97
	if ((r = recvfrom(fd, buf, IBUF_READ_SIZE, 0, NULL, NULL)) == -1) {
98
		if (errno != EAGAIN && errno != EINTR)
99
			log_debug("kmr_recv_msg: error receiving packet");
100
		return;
101
	}
102
103
	memcpy(&kernel_msg, buf, sizeof(kernel_msg));
104
105
	/* we are only interested in kernel messages */
106
	if (kernel_msg.im_mbz != 0)
107
		return;
108
109
	switch (kernel_msg.im_msgtype) {
110
	case IGMPMSG_NOCACHE:
111
		/* verify that dst is a multicast group */
112
		if (!IN_MULTICAST(ntohl(kernel_msg.im_dst.s_addr))) {
113
			log_debug("kmr_recv_msg: kernel providing garbage!");
114
			return;
115
		}
116
117
		/* send MFC entry to RDE */
118
		mfc.origin = kernel_msg.im_src;
119
		mfc.group = kernel_msg.im_dst;
120
		mfc.ifindex = kernel_msg.im_vif;
121
		main_imsg_compose_rde(IMSG_MFC_ADD, 0, &mfc, sizeof(mfc));
122
		break;
123
	case IGMPMSG_WRONGVIF:
124
	case IGMPMSG_WHOLEPKT:
125
	case IGMPMSG_BW_UPCALL:
126
	default:
127
		log_debug("kmr_recv_msg: unhandled msg type %d!",
128
		    kernel_msg.im_msgtype);
129
	}
130
}
131
132
void
133
kmr_mfc_couple(void)
134
{
135
	log_info("kernel multicast forwarding cache coupled");
136
}
137
138
void
139
kmr_mfc_decouple(void)
140
{
141
	log_info("kernel multicast forwarding cache decoupled");
142
}
143
144
void
145
kmroute_clear(void)
146
{
147
148
}
149
150
int
151
mrt_init(int fd)
152
{
153
	int	flag = 1;
154
155
	if (setsockopt(fd, IPPROTO_IP, MRT_INIT, &flag,
156
	    sizeof(flag)) < 0) {
157
		log_warn("mrt_init: error setting MRT_INIT");
158
		return (-1);
159
	}
160
161
	return (0);
162
}
163
164
int
165
mrt_done(int fd)
166
{
167
	int	flag = 0;
168
169
	if (setsockopt(fd, IPPROTO_IP, MRT_DONE, &flag,
170
	    sizeof(flag)) < 0) {
171
		log_warn("mrt_done: error setting MRT_DONE");
172
		return (-1);
173
	}
174
175
	return (0);
176
}
177
178
int
179
mrt_add_vif(int fd, struct iface *iface)
180
{
181
	struct vifctl	vc;
182
183
	vc.vifc_vifi            = iface->ifindex;
184
	vc.vifc_flags           = 0;
185
	vc.vifc_threshold       = 1;
186
	vc.vifc_rate_limit	= 0;
187
	vc.vifc_lcl_addr.s_addr = iface->addr.s_addr;
188
	vc.vifc_rmt_addr.s_addr = 0;
189
190
	if (setsockopt(fd, IPPROTO_IP, MRT_ADD_VIF, &vc,
191
	    sizeof(vc)) < 0) {
192
		log_warn("mrt_add_vif: error adding VIF");
193
		return (-1);
194
	}
195
196
	return (0);
197
}
198
199
void
200
mrt_del_vif(int fd, struct iface *iface)
201
{
202
	vifi_t	 vifi;
203
204
	vifi = iface->ifindex;
205
206
	if (setsockopt(fd, IPPROTO_IP, MRT_DEL_VIF, &vifi,
207
	    sizeof(vifi)) < 0)
208
		log_warn("mrt_del_vif: error deleting VIF");
209
}
210
211
int
212
mrt_add_mfc(int fd, struct mfc *mfc)
213
{
214
	struct mfcctl	 mc;
215
	int		 i;
216
217
	log_debug("mrt_add_mfc: interface %d, group %s", mfc->ifindex,
218
	    inet_ntoa(mfc->group));
219
220
	mc.mfcc_origin = mfc->origin;
221
	mc.mfcc_mcastgrp = mfc->group;
222
	mc.mfcc_parent = mfc->ifindex;
223
224
	for (i = 0; i < MAXVIFS; i++) {
225
		mc.mfcc_ttls[i] = mfc->ttls[i];
226
	}
227
228
	if (setsockopt(fd, IPPROTO_IP, MRT_ADD_MFC, &mc, sizeof(mc))
229
	    < 0) {
230
		log_warnx("mrt_add_mfc: error adding group %s to interface %d",
231
		    inet_ntoa(mfc->group), mfc->ifindex);
232
		return (-1);
233
	}
234
235
	return (0);
236
}
237
238
int
239
mrt_del_mfc(int fd, struct mfc *mfc)
240
{
241
	struct mfcctl	 mc;
242
243
	log_debug("mrt_del_mfc: group %s", inet_ntoa(mfc->group));
244
245
	mc.mfcc_origin = mfc->origin;
246
	mc.mfcc_mcastgrp = mfc->group;
247
248
	if (setsockopt(fd, IPPROTO_IP, MRT_DEL_MFC, &mc, sizeof(mc))
249
	    < 0) {
250
		log_warnx("mrt_del_mfc: error deleting group %s ",
251
		    inet_ntoa(mfc->group));
252
		return (-1);
253
	}
254
255
	return (0);
256
}