filter_telnet.c
author viric@llimona
Mon, 24 Sep 2007 13:59:40 +0200
changeset 38 f1e581c862d5
parent 36 da427c23d755
child 41 954941c6e40a
permissions -rw-r--r--
Improved help. Moving to 0.2.

#include <stdlib.h>
#include "main.h"
#include "filter.h"

enum TState
{
    NOTHING,
    RECEIVED_IAC,
    RECEIVED_OPT,
    SUBNEGOTIATED
};

enum Chars
{
    IAC = 255,
    SB = 250,
    SE = 240
};

struct FTelnet
{
    struct FFilter base;
    enum TState state;
};

static void ftelnet_reset(struct FFilter *ff)
{
    struct FTelnet *ft = (struct FTelnet *) ff;
    dump_line("ftelnet reset.\n");
    ft->state = NOTHING;
}

static int ftelnet_function(struct FFilter *ff, unsigned char c)
{
    struct FTelnet *ft = (struct FTelnet *) ff;

    dump_line("ftelnet_function called\n");
    switch (ft->state)
    {
        case NOTHING:
            dump_line("ftelnet still in NOTHING.\n");
            if (c == IAC)
            {
                dump_line("ftelnet received IAC\n");
                ft->state = RECEIVED_IAC;
                ft->base.matched++;
            }
            break;
        case RECEIVED_IAC:
            if (c == SB)
            {
                dump_line("ftelnet received SB\n");
                ft->state = SUBNEGOTIATED;
                ft->base.matched++;
            } else /* Received the control char */
            {
                ft->state = RECEIVED_OPT;
                dump_line("ftelnet received command.\n");
                ft->base.matched++;
            }
            break;
        case RECEIVED_OPT:
            dump_line("ftelnet received option.\n");
            ft->base.matched++;
            return 1;
            break;
        case SUBNEGOTIATED:
            ft->base.matched++;
            dump_line("ftelnet still in SUBNEGOTIATED.\n");
            if (c == SE)
            {
                dump_line("ftelnet received SE. Filtering.\n");
                return 1;
            }
            break;
    }
    return 0;
}

struct FFilter *new_ftelnet()
{
    struct FTelnet *ft;
    ft = (struct FTelnet *) malloc(sizeof(*ft));

    ft->state = NOTHING;
    ft->base.matched = 0;
    ft->base.function = ftelnet_function;
    ft->base.reset = ftelnet_reset;
    ft->base.callback = 0;

    return (struct FFilter *) ft;
}