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