static
errno_t ppfilter_connect (pp_filter_cookie_t cookie, socket_t so, const struct sockaddr *remote, int connectin)
{
    pp_msg_iprange_t match;
    pg_table_id_t tableid;

    filt_start();

    struct sockaddr_in6 local;
    if (0 != sock_getsockname(so, (struct sockaddr*)&local, sizeof(local)))
        bzero(&local, sizeof(local));

    int protocol = 0;
    (void)sock_gettype(so, NULL, NULL, &protocol);
    int block = match_address(remote, (const struct sockaddr*)&local, protocol, &match, tableid);

    mach_timespec_t now;
    clock_get_calendar_nanotime(&now.tv_sec, (u_int32_t*)&now.tv_nsec);
    u_int32_t lastConnect = sLastConnect;
    if (now.tv_sec >= (lastConnect+1)) {
        (void)ExchangeAtomic(now.tv_sec, &sLastConnect);
        (void)ExchangeAtomic(0, &pp_stats.pps_conns_per_sec);
        (void)ExchangeAtomic(0, &pp_stats.pps_blcks_per_sec);
    }

    // For now we always log even if a log client is not connected, that way
    // we keep as many records as possible so when a log client connects
    // it can save them.
#ifdef notyet
    if (pp_logclients && (block || pp_logallowed)) {
#endif
        const struct sockaddr *to, *from;
        if (!connectin) {
            to = remote;
            from = (const struct sockaddr*)&local;
        } else {
            to = (const struct sockaddr*)&local;
            from = remote;
        }

        ppfilter_log(block, from, to, remote, protocol, &match, tableid, cookie, &now);
#ifdef notyet
    }
#endif

    if (0 == block) {
        connectin ? pp_stat_increment(in_allowed) : pp_stat_increment(out_allowed);
    } else {
        connectin ? pp_stat_increment(in_blocked) : pp_stat_increment(out_blocked);
        block = ECONNREFUSED;
        pp_stat_increment(blcks_per_sec);
    }
    pp_stat_increment(conns_per_sec);

    filt_end();

    return (block);
}
RTDECL(PRTTIMESPEC) RTTimeNow(PRTTIMESPEC pTime)
{
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    uint32_t        uSecs;
    uint32_t        uNanosecs;
#else
    clock_sec_t     uSecs;
    clock_nsec_t    uNanosecs;
#endif
    clock_get_calendar_nanotime(&uSecs, &uNanosecs);
    return RTTimeSpecSetNano(pTime, (uint64_t)uSecs * RT_NS_1SEC + uNanosecs);
}
static pp_dyn_entry_t
pp_dyn_entry_get(void)
{
    int i;
    pp_dyn_entry_t e = NULL;
    u_int32_t now, now_nsec;
    clock_get_calendar_nanotime(&now, &now_nsec);

    for(i=0; i < PP_DYN_ENTRIES_COUNT; ++i) {
        // expire old entries
        if ((pp_dyn_entries[i].ts + 5) > now)
            pp_dyn_entries[i].addr = INADDR_NONE;

        if (INADDR_NONE == pp_dyn_entries[i].addr) {
            e = &pp_dyn_entries[i];
            e->addr = 0;
            e->ts = now;
            OSIncrementAtomic(&pp_dyn_entry_used);
            break;
        }
    }
    return (e);
}