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