#include <stdlib.h>
#include <syslog.h>
#include "firewall.h"

unsigned long netmask[32] = {
    0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
    0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
    0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
    0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
    0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
    0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
    0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
    0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff,
};


#ifdef __GCC__
#define INLINE inline
#else
#define INLINE
#endif


/*
 * match() is a local that attempts to match an connection against
 * a PENTRY
 */
static INLINE int
match(connection *from, connection *to, PENTRY *try)
{
    if (debug) {
	syslog(LOG_DEBUG, "from: %08x (%d) ? %08x (%d)",
		from->ip & try->from.netmask, ntohs(from->port),
		try->from.ip, ntohs(try->from.port));
	syslog(LOG_DEBUG, "  to: %08x (%d) ? %08x (%d)",
		to->ip & try->to.netmask, ntohs(to->port),
		try->to.ip, ntohs(try->to.port));
    }

    if ( (from->ip & try->from.netmask) != try->from.ip)
	return 0;

    if ( (to->ip & try->to.netmask) != try->to.ip)
	return 0;

    if (try->from.port && (try->from.port != from->port))
	return 0;

    if (try->to.port && (try->to.port != to->port))
	return 0;

    if (debug)
	syslog(LOG_DEBUG, "matched!");
    return 1;
} /* match */


/*
 * allow() is the public function that checks to see if a given
 *         ip/port address is legitimate.
 */
allow(connection *from, connection *to, int inbound)
{
    int direction = inbound ? IN : OUT;
    int x;

    if (perms.traf[direction] == 0)
	return DEFAULT;
    for (x=0; x < perms.traf[direction]->nrlist; x++)
	if ( match(from, to, &(perms.traf[direction]->list[x]) ) )
	    return perms.traf[direction]->list[x].todo;
    return DEFAULT;
} /* allow */
