xref: /openbsd/usr.sbin/mrouted/kern.c (revision df69c215)
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 
k_set_rcvbuf(int bufsize)16 void k_set_rcvbuf(int bufsize)
17 {
18     if (setsockopt(igmp_socket, SOL_SOCKET, SO_RCVBUF,
19 		   (char *)&bufsize, sizeof(bufsize)) == -1)
20 	logit(LOG_ERR, errno, "setsockopt SO_RCVBUF %u", bufsize);
21 }
22 
23 
k_hdr_include(int bool)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)) == -1)
29 	logit(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", bool);
30 #endif
31 }
32 
33 
k_set_ttl(int t)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)) == -1)
41 	logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_TTL %u", ttl);
42 }
43 
44 
k_set_loop(int l)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)) == -1)
52 	logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_LOOP %u", loop);
53 }
54 
55 
k_set_if(u_int32_t ifa)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)) == -1)
63 	logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_IF %s",
64 			    inet_fmt(ifa, s1));
65 }
66 
67 
k_join(u_int32_t grp,u_int32_t ifa)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)) == -1)
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 
k_leave(u_int32_t grp,u_int32_t ifa)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)) == -1)
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 
k_init_dvmrp(void)96 void k_init_dvmrp(void)
97 {
98 #ifdef OLD_KERNEL
99     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
100 		   (char *)NULL, 0) == -1)
101 #else
102     int v=1;
103 
104     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
105 		   (char *)&v, sizeof(int)) == -1)
106 #endif
107 	logit(LOG_ERR, errno, "can't enable Multicast routing in kernel");
108 }
109 
110 
k_stop_dvmrp(void)111 void k_stop_dvmrp(void)
112 {
113     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DONE,
114 		   (char *)NULL, 0) == -1)
115 	logit(LOG_WARNING, errno, "can't disable Multicast routing in kernel");
116 }
117 
118 
k_add_vif(vifi_t vifi,struct uvif * v)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)) == -1)
132 	logit(LOG_ERR, errno, "setsockopt MRT_ADD_VIF");
133 }
134 
135 
k_del_vif(vifi_t vifi)136 void k_del_vif(vifi_t vifi)
137 {
138     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_VIF,
139 		   (char *)&vifi, sizeof(vifi)) == -1)
140 	logit(LOG_ERR, errno, "setsockopt MRT_DEL_VIF");
141 }
142 
143 
144 /*
145  * Adds a (source, mcastgrp) entry to the kernel
146  */
k_add_rg(u_int32_t origin,struct gtable * g)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)) == -1) {
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  */
k_del_rg(u_int32_t origin,struct gtable * g)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))) == -1) {
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  */
k_get_version(void)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) == -1)
219 	logit(LOG_ERR, errno,
220 		"getsockopt MRT_VERSION: perhaps your kernel is too old");
221 
222     return vers;
223 #endif
224 }
225