Home | History | Annotate | Line # | Download | only in mrouted
      1 /*	$NetBSD: kern.c,v 1.12 2011/08/31 16:24:59 plunky 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 	logit(LOG_ERR, errno, "setsockopt SO_RCVBUF %u", bufsize);
     21 }
     22 
     23 
     24 void k_hdr_include(int onoff)
     25 {
     26 #ifdef IP_HDRINCL
     27     if (setsockopt(igmp_socket, IPPROTO_IP, IP_HDRINCL,
     28 		   (char *)&onoff, sizeof(onoff)) < 0)
     29 	logit(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", onoff);
     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 	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)) < 0)
     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)) < 0)
     63 	logit(LOG_ERR, errno, "setsockopt IP_MULTICAST_IF %s",
     64 	    		    inet_fmt(ifa));
     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 	logit(LOG_WARNING, errno, "can't join group %s on interface %s",
     78 				inet_fmt(grp),
     79 				inet_fmt(ifa));
     80 }
     81 
     82 
     83 void k_leave(u_int32_t grp, u_int32_t ifa)
     84 {
     85     struct ip_mreq mreq;
     86 
     87     mreq.imr_multiaddr.s_addr = grp;
     88     mreq.imr_interface.s_addr = ifa;
     89 
     90     if (setsockopt(igmp_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
     91 		   (char *)&mreq, sizeof(mreq)) < 0)
     92 	logit(LOG_WARNING, errno, "can't leave group %s on interface %s",
     93 				inet_fmt(grp),
     94 				inet_fmt(ifa));
     95 }
     96 
     97 
     98 void k_init_dvmrp(void)
     99 {
    100 #ifdef OLD_KERNEL
    101     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
    102 		   NULL, 0) < 0)
    103 #else
    104     int v=1;
    105 
    106     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_INIT,
    107 		   (char *)&v, sizeof(int)) < 0)
    108 #endif
    109 	logit(LOG_ERR, errno, "can't enable Multicast routing in kernel");
    110 }
    111 
    112 
    113 void k_stop_dvmrp(void)
    114 {
    115     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DONE,
    116 		   NULL, 0) < 0)
    117 	logit(LOG_WARNING, errno, "can't disable Multicast routing in kernel");
    118 }
    119 
    120 
    121 void k_add_vif(vifi_t vifi, struct uvif *v)
    122 {
    123     struct vifctl vc;
    124 
    125     vc.vifc_vifi            = vifi;
    126     vc.vifc_flags           = v->uv_flags & VIFF_KERNEL_FLAGS;
    127     vc.vifc_threshold       = v->uv_threshold;
    128     vc.vifc_rate_limit	    = v->uv_rate_limit;
    129     vc.vifc_lcl_addr.s_addr = v->uv_lcl_addr;
    130     vc.vifc_rmt_addr.s_addr = v->uv_rmt_addr;
    131 
    132     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_ADD_VIF,
    133 		   (char *)&vc, sizeof(vc)) < 0)
    134 	logit(LOG_ERR, errno, "setsockopt MRT_ADD_VIF");
    135 }
    136 
    137 
    138 void k_del_vif(vifi_t vifi)
    139 {
    140     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_VIF,
    141 		   (char *)&vifi, sizeof(vifi)) < 0)
    142 	logit(LOG_ERR, errno, "setsockopt MRT_DEL_VIF");
    143 }
    144 
    145 
    146 /*
    147  * Adds a (source, mcastgrp) entry to the kernel
    148  */
    149 void k_add_rg(u_int32_t origin, struct gtable *g)
    150 {
    151     struct mfcctl mc;
    152     vifi_t i;
    153 
    154 #ifdef DEBUG_MFC
    155     md_log(MD_ADD, origin, g->gt_mcastgrp);
    156 #endif
    157     /* copy table values so that setsockopt can process it */
    158     mc.mfcc_origin.s_addr = origin;
    159 #ifdef OLD_KERNEL
    160     mc.mfcc_originmask.s_addr = 0xffffffff;
    161 #endif
    162     mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
    163     mc.mfcc_parent = g->gt_route ? g->gt_route->rt_parent : NO_VIF;
    164     for (i = 0; i < numvifs; i++)
    165 	mc.mfcc_ttls[i] = g->gt_ttls[i];
    166 
    167     /* write to kernel space */
    168     if (setsockopt(igmp_socket, IPPROTO_IP, MRT_ADD_MFC,
    169 		   (char *)&mc, sizeof(mc)) < 0) {
    170 #ifdef DEBUG_MFC
    171 	md_log(MD_ADD_FAIL, origin, g->gt_mcastgrp);
    172 #endif
    173 	logit(LOG_WARNING, errno, "setsockopt MRT_ADD_MFC");
    174     }
    175 }
    176 
    177 
    178 /*
    179  * Deletes a (source, mcastgrp) entry from the kernel
    180  */
    181 int k_del_rg(u_int32_t origin, struct gtable *g)
    182 {
    183     struct mfcctl mc;
    184     int retval;
    185 
    186 #ifdef DEBUG_MFC
    187     md_log(MD_DEL, origin, g->gt_mcastgrp);
    188 #endif
    189     /* copy table values so that setsockopt can process it */
    190     mc.mfcc_origin.s_addr = origin;
    191 #ifdef OLD_KERNEL
    192     mc.mfcc_originmask.s_addr = 0xffffffff;
    193 #endif
    194     mc.mfcc_mcastgrp.s_addr = g->gt_mcastgrp;
    195 
    196     /* write to kernel space */
    197     if ((retval = setsockopt(igmp_socket, IPPROTO_IP, MRT_DEL_MFC,
    198 		   (char *)&mc, sizeof(mc))) < 0) {
    199 #ifdef DEBUG_MFC
    200 	md_log(MD_DEL_FAIL, origin, g->gt_mcastgrp);
    201 #endif
    202 	logit(LOG_WARNING, errno, "setsockopt MRT_DEL_MFC");
    203     }
    204 
    205     return retval;
    206 }
    207 
    208 /*
    209  * Get the kernel's idea of what version of mrouted needs to run with it.
    210  */
    211 int k_get_version(void)
    212 {
    213 #ifdef OLD_KERNEL
    214     return -1;
    215 #else
    216     int vers;
    217     socklen_t len = sizeof(vers);
    218 
    219     if (getsockopt(igmp_socket, IPPROTO_IP, MRT_VERSION,
    220 			(char *)&vers, &len) < 0)
    221 	logit(LOG_ERR, errno,
    222 		"getsockopt MRT_VERSION: perhaps your kernel is too old");
    223 
    224     return vers;
    225 #endif
    226 }
    227