/*
**  igmpproxy - IGMP proxy based multicast router
**  Copyright (C) 2005 Johnny Egeland <johnny@rlo.org>
**
**  This program is free software; you can redistribute it and/or modify
**  it under the terms of the GNU General Public License as published by
**  the Free Software Foundation; either version 2 of the License, or
**  (at your option) any later version.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software
**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
**
**----------------------------------------------------------------------------
**
**  This software is derived work from the following software. The original
**  source code has been modified from it's original state by the author
**  of igmpproxy.
**
**  smcroute 0.92 - Copyright (C) 2001 Carsten Schill <carsten@cschill.de>
**  - Licensed under the GNU General Public License, either version 2 or
**    any later version.
**
**  mrouted 3.9-beta3 - Copyright (C) 2002 by The Board of Trustees of
**  Leland Stanford Junior University.
**  - Licensed under the 3-clause BSD license, see Stanford.txt file.
**
*/
/**
*   mroute-api.c
*
*   This module contains the interface routines to the Linux mrouted API
*/


#include "igmpproxy.h"

// MAX_MC_VIFS from mclab.h must have same value as MAXVIFS from mroute.h
#if MAX_MC_VIFS != MAXVIFS
# error "constants don't match, correct mclab.h"
#endif

// need an IGMP socket as interface for the mrouted API
// - receives the IGMP messages
int         MRouterFD;          /* socket for all network I/O  */
char        *recv_buf;          /* input packet buffer         */
char        *send_buf;          /* output packet buffer        */


// my internal virtual interfaces descriptor vector
static struct VifDesc {
    struct IfDesc *IfDp;
} VifDescVc[ MAXVIFS ];

/*
** Initialises the mrouted API and locks it by this exclusively.
**
** returns: - 0 if the functions succeeds
**          - the errno value for non-fatal failure condition
*/
int enableMRouter(void)
{
    int Va = 1;

    if ( (MRouterFD  = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0 )
        my_log( LOG_ERR, errno, "IGMP socket open" );

    if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_INIT,
                     (void *)&Va, sizeof( Va ) ) )
        return errno;

    return 0;
}

/*
** Diable the mrouted API and relases by this the lock.
**
*/
void disableMRouter(void)
{
    if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DONE, NULL, 0 )
         || close( MRouterFD )
    ) {
        MRouterFD = 0;
        my_log( LOG_ERR, errno, "MRT_DONE/close" );
    }

    MRouterFD = 0;
}

/*
 * aimwang: delVIF()
 */
void delVIF( struct IfDesc *IfDp )
{
    struct vifctl VifCtl;

    if ((unsigned int)-1 == IfDp->index)
        return;

    VifCtl.vifc_vifi = IfDp->index;

    my_log( LOG_NOTICE, 0, "removing VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d",
         IfDp->index, IfDp->Flags, IfDp->InAdr.s_addr, IfDp->Name, IfDp->threshold, IfDp->ratelimit);

    if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_VIF,
                     (char *)&VifCtl, sizeof( VifCtl ) ) )
        my_log( LOG_WARNING, errno, "MRT_DEL_VIF" );
}

/*
** Adds the interface '*IfDp' as virtual interface to the mrouted API
**
*/
void addVIF( struct IfDesc *IfDp )
{
    struct vifctl VifCtl;
    struct VifDesc *VifDp;

    /* search free (aimwang: or exist) VifDesc
     */
    for ( VifDp = VifDescVc; VifDp < VCEP( VifDescVc ); VifDp++ ) {
        if ( ! VifDp->IfDp || VifDp->IfDp == IfDp)
            break;
    }

    /* no more space
     */
    if ( VifDp >= VCEP( VifDescVc ) )
        my_log( LOG_ERR, ENOMEM, "addVIF, out of VIF space" );

    VifDp->IfDp = IfDp;

    VifCtl.vifc_vifi  = VifDp - VifDescVc;
    VifCtl.vifc_flags = 0;        /* no tunnel, no source routing, register ? */
    VifCtl.vifc_threshold  = VifDp->IfDp->threshold;    // Packet TTL must be at least 1 to pass them
    VifCtl.vifc_rate_limit = VifDp->IfDp->ratelimit;    // Ratelimit

    VifCtl.vifc_lcl_addr.s_addr = VifDp->IfDp->InAdr.s_addr;
    VifCtl.vifc_rmt_addr.s_addr = INADDR_ANY;

    // Set the index...
    VifDp->IfDp->index = VifCtl.vifc_vifi;

    my_log( LOG_NOTICE, 0, "adding VIF, Ix %d Fl 0x%x IP 0x%08x %s, Threshold: %d, Ratelimit: %d",
         VifCtl.vifc_vifi, VifCtl.vifc_flags,  VifCtl.vifc_lcl_addr.s_addr, VifDp->IfDp->Name,
         VifCtl.vifc_threshold, VifCtl.vifc_rate_limit);

    struct SubnetList *currSubnet;
    for(currSubnet = IfDp->allowednets; currSubnet; currSubnet = currSubnet->next) {
        my_log(LOG_DEBUG, 0, "        Network for [%s] : %s",
            IfDp->Name,
            inetFmts(currSubnet->subnet_addr, currSubnet->subnet_mask, s1));
    }

    if ( setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_VIF,
                     (char *)&VifCtl, sizeof( VifCtl ) ) )
        my_log( LOG_ERR, errno, "MRT_ADD_VIF" );

}

/*
** Adds the multicast routed '*Dp' to the kernel routes
**
** returns: - 0 if the function succeeds
**          - the errno value for non-fatal failure condition
*/
int addMRoute( struct MRouteDesc *Dp )
{
    struct mfcctl CtlReq;
    int rc;

    CtlReq.mfcc_origin    = Dp->OriginAdr;
    CtlReq.mfcc_mcastgrp  = Dp->McAdr;
    CtlReq.mfcc_parent    = Dp->InVif;

    /* copy the TTL vector
     */

    memcpy( CtlReq.mfcc_ttls, Dp->TtlVc, sizeof( CtlReq.mfcc_ttls ) );

    {
        char FmtBuO[ 32 ], FmtBuM[ 32 ];

        my_log( LOG_NOTICE, 0, "Adding MFC: %s -> %s, InpVIf: %d",
             fmtInAdr( FmtBuO, CtlReq.mfcc_origin ),
             fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ),
             (int)CtlReq.mfcc_parent
           );
    }

    rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_ADD_MFC,
                    (void *)&CtlReq, sizeof( CtlReq ) );
    if (rc)
        my_log( LOG_WARNING, errno, "MRT_ADD_MFC" );

    return rc;
}

/*
** Removes the multicast routed '*Dp' from the kernel routes
**
** returns: - 0 if the function succeeds
**          - the errno value for non-fatal failure condition
*/
int delMRoute( struct MRouteDesc *Dp )
{
    struct mfcctl CtlReq;
    int rc;

    CtlReq.mfcc_origin    = Dp->OriginAdr;
    CtlReq.mfcc_mcastgrp  = Dp->McAdr;
    CtlReq.mfcc_parent    = Dp->InVif;

    /* clear the TTL vector
     */
    memset( CtlReq.mfcc_ttls, 0, sizeof( CtlReq.mfcc_ttls ) );

    {
        char FmtBuO[ 32 ], FmtBuM[ 32 ];

        my_log( LOG_NOTICE, 0, "Removing MFC: %s -> %s, InpVIf: %d",
             fmtInAdr( FmtBuO, CtlReq.mfcc_origin ),
             fmtInAdr( FmtBuM, CtlReq.mfcc_mcastgrp ),
             (int)CtlReq.mfcc_parent
           );
    }

    rc = setsockopt( MRouterFD, IPPROTO_IP, MRT_DEL_MFC,
                    (void *)&CtlReq, sizeof( CtlReq ) );
    if (rc)
        my_log( LOG_WARNING, errno, "MRT_DEL_MFC" );

    return rc;
}

/*
** Returns for the virtual interface index for '*IfDp'
**
** returns: - the vitrual interface index if the interface is registered
**          - -1 if no virtual interface exists for the interface
**
*/
int getVifIx( struct IfDesc *IfDp )
{
    struct VifDesc *Dp;

    for ( Dp = VifDescVc; Dp < VCEP( VifDescVc ); Dp++ )
        if ( Dp->IfDp == IfDp )
            return Dp - VifDescVc;

    return -1;
}
