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