/*
 *
 * Copyright (c) 2011 Apple Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <net/if.h>
#include <System/net/pfvar.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <AssertMacros.h>
#include "P2PPacketFilter.h"

#define AIRDROP_ANCHOR_PATH	"com.apple/200.AirDrop"
#define MDNS_ANCHOR_NAME	"Bonjour"
#define MDNS_ANCHOR_PATH	AIRDROP_ANCHOR_PATH "/" MDNS_ANCHOR_NAME

#define PF_DEV_PATH "/dev/pf"
#define BONJOUR_PORT 5353

static int openPFDevice( int * outFD )
{
    int err;
    int fd = open( PF_DEV_PATH, O_RDWR );
    
    if( fd >= 0 )
    {
        err = 0;
        *outFD = fd;
    }
    else
    {
        err = errno;
    }
    
    return err;
}

static int getTicket( int devFD, u_int32_t * outTicket, char * anchorPath )
{
    struct pfioc_trans_e trans_e;
    
    trans_e.rs_num = PF_RULESET_FILTER;
    strlcpy( trans_e.anchor, anchorPath, sizeof( trans_e.anchor ) );
    
    struct pfioc_trans trans;
    
    trans.size = 1;
    trans.esize = sizeof( trans_e );
    trans.array = &trans_e;
    
    int result, ioctlError;
    
    ioctlError = ioctl( devFD, DIOCXBEGIN, &trans );
    if( ioctlError )
    {
        result = errno;
    }
    else
    {
        result = 0;
        *outTicket = trans_e.ticket;
    }
    
    return result;
}

static int commitChange( int devFD, u_int32_t ticket, char * anchorPath )
{
    struct pfioc_trans_e trans_e;
    
    trans_e.rs_num = PF_RULESET_FILTER;
    strlcpy( trans_e.anchor, anchorPath, sizeof( trans_e.anchor ) );
    trans_e.ticket = ticket;
    
    struct pfioc_trans trans;
    
    trans.size = 1;
    trans.esize = sizeof( trans_e );
    trans.array = &trans_e;
    
    int result, ioctlError;
    
    ioctlError = ioctl( devFD, DIOCXCOMMIT, &trans );
    if( ioctlError )
        result = errno;
    else
        result = 0;
    
    return result;
}

static int getPoolTicket( int devFD, u_int32_t * outPoolTicket )
{
    struct pfioc_pooladdr pp;
    
    int result, ioctlError;
    
    ioctlError = ioctl( devFD, DIOCBEGINADDRS, &pp );
    if( ioctlError )
    {
        result = errno;
    }
    else
    {
        result = 0;
        *outPoolTicket = pp.ticket;
    }
    
    return result;
}

static int addRule( int devFD, struct pfioc_rule * pr )
{
    int result, ioctlResult;
    
    ioctlResult = ioctl( devFD, DIOCADDRULE, pr );
    if( ioctlResult )
        result = errno;
    else
        result = 0;
    
    return result;
}

static void initRuleHeader( struct pfioc_rule * pr,
                             u_int32_t ticket,
                             u_int32_t poolTicket,
							 char * anchorPath )
{
    pr->action = PF_CHANGE_NONE;
    pr->ticket = ticket;
    pr->pool_ticket = poolTicket;
    strlcpy( pr->anchor, anchorPath, sizeof( pr->anchor ) );
}

// allow inbound traffice on the Bonjour port (5353) 
static void initBonjourRule( struct pfioc_rule * pr,
                              const char * interfaceName,
                              u_int32_t ticket,
                              u_int32_t poolTicket, 
							  char * anchorPath )
{
    memset( pr, 0, sizeof( *pr ) );
    
    // Header
    initRuleHeader( pr, ticket, poolTicket, anchorPath );
    
    // Rule
    pr->rule.dst.xport.range.port[0] = htons( BONJOUR_PORT );
    pr->rule.dst.xport.range.op = PF_OP_EQ;
    
    strlcpy( pr->rule.ifname, interfaceName, sizeof( pr->rule.ifname ) );
    
    pr->rule.action = PF_PASS;
    pr->rule.direction = PF_IN;
    pr->rule.keep_state = 1;
    pr->rule.af = AF_INET6;
    pr->rule.proto = IPPROTO_UDP;
    pr->rule.extfilter = PF_EXTFILTER_APD;
}

// allow outbound TCP connections and return traffic for those connections
static void initOutboundTCPRule( struct pfioc_rule * pr,
                             const char * interfaceName,
                             u_int32_t ticket,
                             u_int32_t poolTicket, 
							 char * anchorPath )
{
    memset( pr, 0, sizeof( *pr ) );
    
    // Header
    initRuleHeader( pr, ticket, poolTicket, anchorPath );
    
    // Rule
    strlcpy( pr->rule.ifname, interfaceName, sizeof( pr->rule.ifname ) );
    
    pr->rule.action = PF_PASS;
    pr->rule.direction = PF_OUT;
    pr->rule.keep_state = 1;
    pr->rule.proto = IPPROTO_TCP;
}

// allow inbound traffic on the specified port and protocol
static void initPortRule( struct pfioc_rule * pr,
                              const char * interfaceName,
                              u_int32_t ticket,
                              u_int32_t poolTicket,
							  char * anchorPath,
							  u_int16_t port,
							  u_int16_t protocol )
{
    memset( pr, 0, sizeof( *pr ) );
    
    // Header
    initRuleHeader( pr, ticket, poolTicket, anchorPath );
    
    // Rule
	// mDNSResponder passes the port in Network Byte Order, so htons(port) is not required 
    pr->rule.dst.xport.range.port[0] = port;
    pr->rule.dst.xport.range.op = PF_OP_EQ;
    
    strlcpy( pr->rule.ifname, interfaceName, sizeof( pr->rule.ifname ) );
    
    pr->rule.action = PF_PASS;
    pr->rule.direction = PF_IN;
    pr->rule.keep_state = 1;
    pr->rule.af = AF_INET6;
    pr->rule.proto = protocol;
    pr->rule.extfilter = PF_EXTFILTER_APD;
}

// allow inbound traffice on the Bonjour port (5353) and the specified port and protocol
int P2PPacketFilterAddBonjourRuleSet(const char * interfaceName, u_int16_t port, u_int16_t protocol )
{
    int result;
    u_int32_t ticket, poolTicket;
    int devFD = -1;
	char * anchorPath = MDNS_ANCHOR_PATH;
	
    result = openPFDevice( &devFD );
    require( result == 0, exit );
    
    result = getTicket( devFD, &ticket, anchorPath );
    require( result == 0, exit );
    
    result = getPoolTicket( devFD, &poolTicket );
    require( result == 0, exit );
    
    struct pfioc_rule pr;
    
    // allow inbound Bonjour traffice to port 5353 
    initBonjourRule( &pr, interfaceName, ticket, poolTicket, anchorPath);
    
    result = addRule( devFD, &pr );
    require( result == 0, exit );
    
    // open inbound port for service
    initPortRule( &pr, interfaceName, ticket, poolTicket, anchorPath, port, protocol );
    
    result = addRule( devFD, &pr );
    require( result == 0, exit );
    
    // allow outbound TCP connections and return traffic for those connections
    initOutboundTCPRule( &pr, interfaceName, ticket, poolTicket, anchorPath);
    
    result = addRule( devFD, &pr );
    require( result == 0, exit );
    
    result = commitChange( devFD, ticket, anchorPath );
    require( result == 0, exit );
    
exit:
    
    if( devFD >= 0 )
        close( devFD );
    
    return result;
}

int P2PPacketFilterClearBonjourRules()
{
	int result;
	int pfDev = -1;
	u_int32_t ticket;
	char * anchorPath = MDNS_ANCHOR_PATH;
	
	result = openPFDevice( &pfDev );
	require( result == 0, exit );
	
	result = getTicket( pfDev, &ticket, anchorPath );
	require( result == 0, exit );
	
	result = commitChange( pfDev, ticket, anchorPath );
	
exit:
	
	if( pfDev >= 0 )
		close( pfDev );

	return result;
}

