Home | History | Annotate | Line # | Download | only in mrouted
      1  1.12   plunky /*	$NetBSD: kern.c,v 1.12 2011/08/31 16:24:59 plunky 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.11   dyoung void k_hdr_include(int onoff)
     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.11   dyoung 		   (char *)&onoff, sizeof(onoff)) < 0)
     29  1.11   dyoung 	logit(LOG_ERR, errno, "setsockopt IP_HDRINCL %u", onoff);
     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.12   plunky 		   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.12   plunky 		   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.10      mrg     socklen_t 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