
#include "queso.h"

/***************************************************************************/
/*
** We need to monitor packets so we
** simply add a Miami Packets Monitor.
**/

LONG ASM
initSniffer(REG(a0) struct global *g)
{
    g->hook.h_Entry    = (APTR)sniff;
    g->hook.h_SubEntry = NULL;
    g->hook.h_Data     = g;

    return (g->handle = MiamiPFAddHook(&g->hook,g->device,NULL)) ? 0 : ERR_NoSniffer;
}

/***************************************************************************/
/*
** Closes the added Miami Packets Monitor.
**/

void ASM
closeSniffer(REG(a0) struct global *g)
{
    if (g->handle)
    {
        MiamiPFRemoveHook(g->handle);
        g->handle = NULL;
    }
}

/***************************************************************************/
/*
** This is the hook called async by Miami
**/

struct packet
{
    struct ip       ip;
    struct tcphdr   tcp;
};

ULONG SAVEDS ASM
sniff(REG(a0) struct Hook *hook,REG(a2) APTR handle,REG(a1) struct MiamiPFBuffer *buf)
{
    register struct global  *g = hook->h_Data;
    register struct packet  *p;
    register int            n;

    if (buf->length<40) return 0;

    p = (struct packet *)buf->data;
    if ((p->ip.ip_v!=4) ||
        (p->ip.ip_p!=6) ||
        (p->ip.ip_src.s_addr!=g->srch) ||
        (p->ip.ip_dst.s_addr!=g->dsth) ||
        (p->tcp.th_sport!=g->srcp) ||
        ((n = p->tcp.th_dport - g->start)<0) || (n>MAXPKT) ||
        g->a[n].set) return 0;

    ObtainSemaphore(&g->sem);
    g->a[n].seq  = p->tcp.th_seq ? 1 : 0;
    g->a[n].ack  = p->tcp.th_ack ? 1 : 0;
    g->a[n].win  = p->tcp.th_win;
    g->a[n].flag = p->tcp.th_flags;
    g->a[n].urg  = p->tcp.th_urp ? 1 : 0;
    g->a[n].set  = 1;
    g->count++;
    ReleaseSemaphore(&g->sem);

    if (g->flags & QFLG_Debug)
    {
        g->ma[n].ptype = n;
        g->ma[n].link.mn_Length = sizeof(struct dMsg);
        memcpy(&g->ma[n].tcp,&p->tcp,sizeof(struct tcphdr));
        PutMsg(&g->port,(struct Message *)(g->ma+n));
    }
    else Signal((struct Task *)g->this,1<<g->sigBit);

    return 0;
}

/***************************************************************************/
