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(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 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 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 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 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 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 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 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 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 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 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 */ 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 */ 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 */ 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