1a17240f2Sderaadt /* $NetBSD: kern.c,v 1.4 1995/12/10 10:07:03 mycroft Exp $ */
2df930be7Sderaadt
3df930be7Sderaadt /*
4df930be7Sderaadt * The mrouted program is covered by the license in the accompanying file
5df930be7Sderaadt * named "LICENSE". Use of the mrouted program represents acceptance of
6df930be7Sderaadt * the terms and conditions listed in that file.
7df930be7Sderaadt *
8df930be7Sderaadt * The mrouted program is COPYRIGHT 1989 by The Board of Trustees of
9df930be7Sderaadt * Leland Stanford Junior University.
10df930be7Sderaadt */
11df930be7Sderaadt
12df930be7Sderaadt
13df930be7Sderaadt #include "defs.h"
14df930be7Sderaadt
15df930be7Sderaadt
k_set_rcvbuf(int bufsize)165017e83eSderaadt void k_set_rcvbuf(int bufsize)
17df930be7Sderaadt {
18df930be7Sderaadt if (setsockopt(igmp_socket, SOL_SOCKET, SO_RCVBUF,
19*df69c215Sderaadt (char *)&bufsize, sizeof(bufsize)) == -1)
2040443a2fSmillert logit(LOG_ERR, errno, "setsockopt SO_RCVBUF %u", bufsize);
21df930be7Sderaadt }
22df930be7Sderaadt
23df930be7Sderaadt
k_hdr_include(int bool)245017e83eSderaadt void k_hdr_include(int bool)
25df930be7Sderaadt {
26df930be7Sderaadt #ifdef IP_HDRINCL
27df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, IP_HDRINCL,
28*df69c215Sderaadt (char *)&bool, sizeof(bool)) == -1)
2940443a2fSmillert logit(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", bool);
30df930be7Sderaadt #endif
31df930be7Sderaadt }
32df930be7Sderaadt
33df930be7Sderaadt
k_set_ttl(int t)345017e83eSderaadt void k_set_ttl(int t)
35df930be7Sderaadt {
36df930be7Sderaadt u_char ttl;
37df930be7Sderaadt
38df930be7Sderaadt ttl = t;
39df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_TTL,
40*df69c215Sderaadt (char *)&ttl, sizeof(ttl)) == -1)
4140443a2fSmillert logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_TTL %u", ttl);
42df930be7Sderaadt }
43df930be7Sderaadt
44df930be7Sderaadt
k_set_loop(int l)455017e83eSderaadt void k_set_loop(int l)
46df930be7Sderaadt {
47df930be7Sderaadt u_char loop;
48df930be7Sderaadt
49df930be7Sderaadt loop = l;
50df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_LOOP,
51*df69c215Sderaadt (char *)&loop, sizeof(loop)) == -1)
5240443a2fSmillert logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_LOOP %u", loop);
53df930be7Sderaadt }
54df930be7Sderaadt
55df930be7Sderaadt
k_set_if(u_int32_t ifa)565017e83eSderaadt void k_set_if(u_int32_t ifa)
57df930be7Sderaadt {
58df930be7Sderaadt struct in_addr adr;
59df930be7Sderaadt
60df930be7Sderaadt adr.s_addr = ifa;
61df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, IP_MULTICAST_IF,
62*df69c215Sderaadt (char *)&adr, sizeof(adr)) == -1)
6340443a2fSmillert logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_IF %s",
64df930be7Sderaadt inet_fmt(ifa, s1));
65df930be7Sderaadt }
66df930be7Sderaadt
67df930be7Sderaadt
k_join(u_int32_t grp,u_int32_t ifa)685017e83eSderaadt void k_join(u_int32_t grp, u_int32_t ifa)
69df930be7Sderaadt {
70df930be7Sderaadt struct ip_mreq mreq;
71df930be7Sderaadt
72df930be7Sderaadt mreq.imr_multiaddr.s_addr = grp;
73df930be7Sderaadt mreq.imr_interface.s_addr = ifa;
74df930be7Sderaadt
75df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
76*df69c215Sderaadt (char *)&mreq, sizeof(mreq)) == -1)
7740443a2fSmillert logit(LOG_WARNING, errno, "can't join group %s on interface %s",
78df930be7Sderaadt inet_fmt(grp, s1), inet_fmt(ifa, s2));
79df930be7Sderaadt }
80df930be7Sderaadt
81df930be7Sderaadt
k_leave(u_int32_t grp,u_int32_t ifa)825017e83eSderaadt void k_leave(u_int32_t grp, u_int32_t ifa)
83df930be7Sderaadt {
84df930be7Sderaadt struct ip_mreq mreq;
85df930be7Sderaadt
86df930be7Sderaadt mreq.imr_multiaddr.s_addr = grp;
87df930be7Sderaadt mreq.imr_interface.s_addr = ifa;
88df930be7Sderaadt
89df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
90*df69c215Sderaadt (char *)&mreq, sizeof(mreq)) == -1)
9140443a2fSmillert logit(LOG_WARNING, errno, "can't leave group %s on interface %s",
92df930be7Sderaadt inet_fmt(grp, s1), inet_fmt(ifa, s2));
93df930be7Sderaadt }
94df930be7Sderaadt
95df930be7Sderaadt
k_init_dvmrp(void)965017e83eSderaadt void k_init_dvmrp(void)
97df930be7Sderaadt {
98df930be7Sderaadt #ifdef OLD_KERNEL
99df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
100*df69c215Sderaadt (char *)NULL, 0) == -1)
101df930be7Sderaadt #else
102df930be7Sderaadt int v=1;
103df930be7Sderaadt
104df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
105*df69c215Sderaadt (char *)&v, sizeof(int)) == -1)
106df930be7Sderaadt #endif
10740443a2fSmillert logit(LOG_ERR, errno, "can't enable Multicast routing in kernel");
108df930be7Sderaadt }
109df930be7Sderaadt
110df930be7Sderaadt
k_stop_dvmrp(void)1115017e83eSderaadt void k_stop_dvmrp(void)
112df930be7Sderaadt {
113df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DONE,
114*df69c215Sderaadt (char *)NULL, 0) == -1)
11540443a2fSmillert logit(LOG_WARNING, errno, "can't disable Multicast routing in kernel");
116df930be7Sderaadt }
117df930be7Sderaadt
118df930be7Sderaadt
k_add_vif(vifi_t vifi,struct uvif * v)1195017e83eSderaadt void k_add_vif(vifi_t vifi, struct uvif *v)
120df930be7Sderaadt {
121df930be7Sderaadt struct vifctl vc;
122df930be7Sderaadt
123df930be7Sderaadt vc.vifc_vifi = vifi;
124df930be7Sderaadt vc.vifc_flags = v->uv_flags & VIFF_KERNEL_FLAGS;
125df930be7Sderaadt vc.vifc_threshold = v->uv_threshold;
126df930be7Sderaadt vc.vifc_rate_limit = v->uv_rate_limit;
127df930be7Sderaadt vc.vifc_lcl_addr.s_addr = v->uv_lcl_addr;
128df930be7Sderaadt vc.vifc_rmt_addr.s_addr = v->uv_rmt_addr;
129df930be7Sderaadt
130df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, MRT_ADD_VIF,
131*df69c215Sderaadt (char *)&vc, sizeof(vc)) == -1)
13240443a2fSmillert logit(LOG_ERR, errno, "setsockopt MRT_ADD_VIF");
133df930be7Sderaadt }
134df930be7Sderaadt
135df930be7Sderaadt
k_del_vif(vifi_t vifi)1365017e83eSderaadt void k_del_vif(vifi_t vifi)
137df930be7Sderaadt {
138df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_VIF,
139*df69c215Sderaadt (char *)&vifi, sizeof(vifi)) == -1)
14040443a2fSmillert logit(LOG_ERR, errno, "setsockopt MRT_DEL_VIF");
141df930be7Sderaadt }
142df930be7Sderaadt
143df930be7Sderaadt
144df930be7Sderaadt /*
145df930be7Sderaadt * Adds a (source, mcastgrp) entry to the kernel
146df930be7Sderaadt */
k_add_rg(u_int32_t origin,struct gtable * g)1475017e83eSderaadt void k_add_rg(u_int32_t origin, struct gtable *g)
148df930be7Sderaadt {
149df930be7Sderaadt struct mfcctl mc;
150a17240f2Sderaadt vifi_t i;
151df930be7Sderaadt
152a17240f2Sderaadt #ifdef DEBUG_MFC
15340443a2fSmillert md_logit(MD_ADD, origin, g->gt_mcastgrp);
154a17240f2Sderaadt #endif
155df930be7Sderaadt /* copy table values so that setsockopt can process it */
156df930be7Sderaadt mc.mfcc_origin.s_addr = origin;
157df930be7Sderaadt #ifdef OLD_KERNEL
158df930be7Sderaadt mc.mfcc_originmask.s_addr = 0xffffffff;
159df930be7Sderaadt #endif
160df930be7Sderaadt mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
161df930be7Sderaadt mc.mfcc_parent = g->gt_route ? g->gt_route->rt_parent : NO_VIF;
162df930be7Sderaadt for (i = 0; i < numvifs; i++)
163df930be7Sderaadt mc.mfcc_ttls[i] = g->gt_ttls[i];
164df930be7Sderaadt
165df930be7Sderaadt /* write to kernel space */
166df930be7Sderaadt if (setsockopt(igmp_socket, IPPROTO_IP, MRT_ADD_MFC,
167*df69c215Sderaadt (char *)&mc, sizeof(mc)) == -1) {
168a17240f2Sderaadt #ifdef DEBUG_MFC
16940443a2fSmillert md_logit(MD_ADD_FAIL, origin, g->gt_mcastgrp);
170a17240f2Sderaadt #endif
17140443a2fSmillert logit(LOG_WARNING, errno, "setsockopt MRT_ADD_MFC");
172df930be7Sderaadt }
173a17240f2Sderaadt }
174df930be7Sderaadt
175df930be7Sderaadt
176df930be7Sderaadt /*
177df930be7Sderaadt * Deletes a (source, mcastgrp) entry from the kernel
178df930be7Sderaadt */
k_del_rg(u_int32_t origin,struct gtable * g)1795017e83eSderaadt int k_del_rg(u_int32_t origin, struct gtable *g)
180df930be7Sderaadt {
181df930be7Sderaadt struct mfcctl mc;
182a17240f2Sderaadt int retval;
183df930be7Sderaadt
184a17240f2Sderaadt #ifdef DEBUG_MFC
18540443a2fSmillert md_logit(MD_DEL, origin, g->gt_mcastgrp);
186a17240f2Sderaadt #endif
187df930be7Sderaadt /* copy table values so that setsockopt can process it */
188df930be7Sderaadt mc.mfcc_origin.s_addr = origin;
189df930be7Sderaadt #ifdef OLD_KERNEL
190df930be7Sderaadt mc.mfcc_originmask.s_addr = 0xffffffff;
191df930be7Sderaadt #endif
192df930be7Sderaadt mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
193df930be7Sderaadt
194df930be7Sderaadt /* write to kernel space */
195df930be7Sderaadt if ((retval = setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_MFC,
196*df69c215Sderaadt (char *)&mc, sizeof(mc))) == -1) {
197a17240f2Sderaadt #ifdef DEBUG_MFC
19840443a2fSmillert md_logit(MD_DEL_FAIL, origin, g->gt_mcastgrp);
199a17240f2Sderaadt #endif
20040443a2fSmillert logit(LOG_WARNING, errno, "setsockopt MRT_DEL_MFC");
201a17240f2Sderaadt }
202df930be7Sderaadt
203df930be7Sderaadt return retval;
204df930be7Sderaadt }
205df930be7Sderaadt
206df930be7Sderaadt /*
207df930be7Sderaadt * Get the kernel's idea of what version of mrouted needs to run with it.
208df930be7Sderaadt */
k_get_version(void)2095017e83eSderaadt int k_get_version(void)
210df930be7Sderaadt {
211a17240f2Sderaadt #ifdef OLD_KERNEL
212a17240f2Sderaadt return -1;
213a17240f2Sderaadt #else
214df930be7Sderaadt int vers;
215df930be7Sderaadt int len = sizeof(vers);
216df930be7Sderaadt
217df930be7Sderaadt if (getsockopt(igmp_socket, IPPROTO_IP, MRT_VERSION,
218*df69c215Sderaadt (char *)&vers, &len) == -1)
21940443a2fSmillert logit(LOG_ERR, errno,
220df930be7Sderaadt "getsockopt MRT_VERSION: perhaps your kernel is too old");
221df930be7Sderaadt
222df930be7Sderaadt return vers;
223a17240f2Sderaadt #endif
224df930be7Sderaadt }
225