Home | History | Annotate | Line # | Download | only in mrouted
kern.c revision 1.5
      1 /*	$NetBSD: kern.c,v 1.5 2002/07/14 16:30:42 wiz 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)) < 0)
     20 	log(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)) < 0)
     29 	log(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)) < 0)
     41 	log(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)) < 0)
     52 	log(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)) < 0)
     63 	log(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)) < 0)
     77 	log(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)) < 0)
     91 	log(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) < 0)
    101 #else
    102     int v=1;
    103 
    104     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
    105 		   (char *)&v, sizeof(int)) < 0)
    106 #endif
    107 	log(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) < 0)
    115 	log(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)) < 0)
    132 	log(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)) < 0)
    140 	log(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_log(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)) < 0) {
    168 #ifdef DEBUG_MFC
    169 	md_log(MD_ADD_FAIL, origin, g->gt_mcastgrp);
    170 #endif
    171 	log(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_log(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))) < 0) {
    197 #ifdef DEBUG_MFC
    198 	md_log(MD_DEL_FAIL, origin, g->gt_mcastgrp);
    199 #endif
    200 	log(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) < 0)
    219 	log(LOG_ERR, errno,
    220 		"getsockopt MRT_VERSION: perhaps your kernel is too old");
    221 
    222     return vers;
    223 #endif
    224 }
    225