kern.c revision 1.3 1 /* $NetBSD: kern.c,v 1.3 1995/10/09 03:51:43 thorpej 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_long origin;
161 struct gtable *g;
162 {
163 struct mfcctl mc;
164 int i;
165
166 /* copy table values so that setsockopt can process it */
167 mc.mfcc_origin.s_addr = origin;
168 #ifdef OLD_KERNEL
169 mc.mfcc_originmask.s_addr = 0xffffffff;
170 #endif
171 mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
172 mc.mfcc_parent = g->gt_route ? g->gt_route->rt_parent : NO_VIF;
173 for (i = 0; i < numvifs; i++)
174 mc.mfcc_ttls[i] = g->gt_ttls[i];
175
176 /* write to kernel space */
177 if (setsockopt(igmp_socket, IPPROTO_IP, MRT_ADD_MFC,
178 (char *)&mc, sizeof(mc)) < 0)
179 log(LOG_WARNING, errno, "setsockopt MRT_ADD_MFC");
180 }
181
182
183 /*
184 * Deletes a (source, mcastgrp) entry from the kernel
185 */
186 int k_del_rg(origin, g)
187 u_long origin;
188 struct gtable *g;
189 {
190 struct mfcctl mc;
191 int retval, i;
192
193 /* copy table values so that setsockopt can process it */
194 mc.mfcc_origin.s_addr = origin;
195 #ifdef OLD_KERNEL
196 mc.mfcc_originmask.s_addr = 0xffffffff;
197 #endif
198 mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
199
200 /* write to kernel space */
201 if ((retval = setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_MFC,
202 (char *)&mc, sizeof(mc))) < 0)
203 log(LOG_WARNING, errno, "setsockopt MRT_DEL_MFC");
204
205 return retval;
206 }
207
208 /*
209 * Get the kernel's idea of what version of mrouted needs to run with it.
210 */
211 int k_get_version()
212 {
213 int vers;
214 int len = sizeof(vers);
215
216 if (getsockopt(igmp_socket, IPPROTO_IP, MRT_VERSION,
217 (char *)&vers, &len) < 0)
218 log(LOG_ERR, errno,
219 "getsockopt MRT_VERSION: perhaps your kernel is too old");
220
221 return vers;
222 }
223