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