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