Home | History | Annotate | Line # | Download | only in mrouted
kern.c revision 1.4
      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