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