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