xref: /netbsd/usr.sbin/mrouted/kern.c (revision bf9ec67e)
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