/* table.h -- this header file defines a dispatch table for Charon.
 *
 * Created by:	Derek Atkins <warlord@MIT.EDU>
 *
 * $Source: /afs/net.mit.edu/user/warlord/Thesis/src/lib/RCS/table.h,v $
 * $Author: warlord $
 *
 */

#include <warlord-copyright.h>

#ifndef _TABLE_H
#define _TABLE_H

#include <stdio.h>
#include <charon_prot.h>
#include "crn.h"

/* A state is an array of functions and integers, with an index of
 * a packet type.  The next_state is a number which says which state
 * it should go to next on a valid return (i.e., 0) from the function.
 */
typedef struct _state_t {
  int	(*entry)();		/* function to call when entering this state */
  int	maxstate;		/* Highest state in this table */
  int	(*fcn[MAX_NUM_PKTS])();	/* functions to process packet */
  int	next_state[MAX_NUM_PKTS];
} state_t;

/* A dispatch table is an array of state_t, where the index is the
 * state or the FSM.  We need one of these for each version, for
 * each side of the protcol.  There should be 16 offsets into the
 * array: one for each of the 16 possible packet types.  Use NULL
 * for an invalid packet type (error).
 */
typedef state_t *d_table;

/* A version table is an array of dispatch tables for different versions
 * of the protocol.  We need one of these for each side of the protocol.
 */
typedef d_table *v_table;

/*************************************************************/
/* Below this line is a set of definitions for the protocol. 
 * It is in the form of a Finite State Machine.   Each version
 * has its own FSM, defined as an array of states.
 */

/* States for the client side of version 2 */
static state_t cv2_d_table[] = {
  {				/* state 0 */
    SendVersionInfo,
    2,
    {CheckStatus, NULL, ProcessVersion, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL},
    {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

  {				/* state 1 */
    NULL,
    2,
    {CheckStatus, NULL, NULL, ProcessInfo,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL},
    {1, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

  {				/* state 2 */
    NULL,
    2,
    {CheckStatus, NULL, NULL, NULL,
       ProcessServerKDC, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL},
    {2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
};

/* States for the server side of version 2 */
static state_t sv2_d_table[] = {
  {				/* state 0 */
    NULL,
    2,
    {CheckStatus, ProcessVersion, NULL, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL},
    {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

  {				/* state 1 */
    SendInfoAndKDCPkts,
    2,
    {CheckStatus, NULL, NULL, NULL,
       NULL, ProcessClientKDC, ProcessCliAuth, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL},
    {1, 0, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0}},

  {				/* state 2 */
    NULL,
    2,
    {CheckStatus, NULL, NULL, NULL,
       NULL, NULL, ProcessCliAuth, NULL,
       NULL, NULL, NULL, NULL,
       NULL, NULL, NULL, NULL},
    {2, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0}}
};

/* Client Version Table */
static d_table c_v_table[] = {NULL, NULL, cv2_d_table, NULL};

/* Server Version Table */
static d_table s_v_table[] = {NULL, NULL, sv2_d_table, NULL};

/* A command table is an array of version tables, for the client side
 * and server side of the protocol.  There is only one of these!  This
 * assumes that a client is 0, and a server is 1.
 */
static v_table command_table[] = {c_v_table, s_v_table};

#endif /* _TABLE_H */
