Home | History | Annotate | Line # | Download | only in mrouted
kern.c revision 1.10.38.1
      1  1.10.38.1   bouyer /*	$NetBSD: kern.c,v 1.10.38.1 2011/03/05 15:11:02 bouyer 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.10.38.1   bouyer 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.10.38.1   bouyer 		   (char *)&onoff, sizeof(onoff)) < 0)
     29  1.10.38.1   bouyer 	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.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.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