/*
** pat_tr.c for  in 
** 
** Made by 
** Login   <vianney@epita.fr>
** 
** Started on  Wed Sep  1 06:40:43 1999 
** Last update Thu Oct 28 20:19:26 1999 
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include "pat_tr.h"
#include "pat_ip.h"
#include "pat_arp.h"
#include "pat_data.h"
#include "pat_buf.h"
#include "pat_16.h"
#include "pat_8.h"
#include "pat_mac.h"
#include "pat_ieee802.h"

/* minimalist support for token ring, only llc without rif is recognized 
   for now. */

t_bit_field	trrif_rt_bit_field = 
{
  0,2
};

t_bit_field	trrif_lth_bit_field = 
{
  3,7
};

t_bit_field	trrif_d_bit_field = 
{
  8,8
};

t_bit_field	trrif_lf_bit_field = 
{
  9,14
};

t_bit_field	trrif_r_bit_field = 
{
  15,15
};

t_field				trrif_fields[] = 
{
  {"rcf",	0,		&nu16_pat,		NULL},
  {"rt",	0,		&nu16bitfield_pat,	&trrif_rt_bit_field},
  {"lth",	0,		&nu16bitfield_pat,	&trrif_lth_bit_field},
  {"d",		0,		&nu16bitfield_pat,	&trrif_d_bit_field},
  {"lf",	0,		&nu16bitfield_pat,	&trrif_lf_bit_field},
  {"r",		0,		&nu16bitfield_pat,	&trrif_r_bit_field},
  NULL_FIELD
};

char				*trrif_itmpl = "\n\
<table _name=trrif[%i%] width=100%%%% bgcolor=\"%%trrifColor%%\">\n\
<tr>\n\
<td align=center width=18%%%%>\n\
<a href=\"set(trrif[%i%].rt)\">%%trrif[%i%].rt%%</a>\n\
</td>\n\
<td align=center width=31%%%%>\n\
<a href=\"set(trrif[%i%].lth)\">%%trrif[%i%].lth%%</a>\n\
</td>\n\
<td align=center width=6%%%%>\n\
<a href=\"set(trrif[%i%].d)\">%%trrif[%i%].d%%</a>\n\
</td>\n\
<td align=center width=37%%%%>\n\
<a href=\"set(trrif[%i%].lf)\">%%trrif[%i%].lf%%</a>\n\
</td>\n\
<td align=center width=6%%%%>\n\
<a href=\"set(trrif[%i%].r)\">%%trrif[%i%].r%%</a>\n\
</td>\n\
</tr>\n\
</table>\n\
<br>\n\
";

int	trrif_chan;

PAT_NAME_GENERIC(trrif_pat_name,
		 (VOID_PTR)&trrif_chan,
		 "trrif")

PAT_GET_FIELD_GENERIC(trrif_pat_get_field,
		      trrif_fields)

PAT_SET_FIELD_GENERIC(trrif_pat_set_field,
		      trrif_fields)

PAT_GET_FIELDS_GENERIC(trrif_pat_get_fields,
		       trrif_fields)

PAT_GET_FIELD_PAT_GENERIC(trrif_pat_get_field_pat,
			  trrif_fields)

PAT_GET_TMPL_GENERIC(trrif_pat_get_tmpl,
		     (VOID_PTR)&trrif_chan,
		     trrif_itmpl)

PAT_OFF_DECL(trrif_pat_off)
{
  t_u16		rcf;
  t_u16		lth;

  if (len < 2)
    return (ERR_PAT_TRUNC_PAT);
  rcf = safe_ntohs((t_u16 *)buf);
  bit_field_u16_get(&rcf,
		    &lth,
		    trrif_lth_bit_field.from,
		    trrif_lth_bit_field.to);
  (*off_return) = lth;
  return (0);
}

PAT_SUB_DECL(trrif_pat_sub)
{
  (*pat_return) = &data_pat;
  return (0);
}

t_pat				trrif_pat = 
{
  trrif_pat_name,		/* t_pat_name_proc		*/
  trrif_pat_off,		/* t_pat_off_proc		*/
  trrif_pat_sub,		/* t_pat_sub_proc		*/
  NULL,				/* t_pat_sum_proc		*/
  trrif_pat_get_field,		/* t_pat_get_field_proc		*/
  trrif_pat_set_field,		/* t_pat_set_field_proc		*/
  trrif_pat_get_fields,		/* t_pat_get_fields_proc	*/
  trrif_pat_get_tmpl,		/* t_pat_get_tmpl_proc		*/
  NULL,				/* t_pat_get_tmpl2_proc		*/
  NULL,				/* t_pat_has_opt_proc		*/
  NULL,				/* t_pat_adapt_len_proc		*/
  trrif_pat_get_field_pat,	/* t_pat_get_field_pat_proc	*/
  NULL,				/* t_pat_extract_proc		*/
  NULL,				/* t_pat_insert_proc		*/
  NULL,				/* t_pat_get_choices_proc	*/
};

t_bit_field	ac_priority_bit_field = 
{
  0,2
};

t_bit_field	ac_token_bit_field = 
{
  3,3
};

t_assoc		ac_token_assocs[] = 
{
  {"token",	(VOID_PTR)0},
  {"frame",	(VOID_PTR)1},
  NULL_ASSOC
};

t_bit_field_assocs_data	ac_token_bfad =
{
  &ac_token_bit_field,
  ac_token_assocs
};

t_bit_field	ac_monitor_bit_field = 
{
  4,4
};

t_bit_field	ac_reservation_bit_field = 
{
  5,7
};

t_bit_field	fc_frametype_bit_field = 
{
  0,1
};

t_assoc		fc_frametype_assocs[] = 
{
  {"mac",	(VOID_PTR)0},
  {"llc",	(VOID_PTR)1},
  NULL_ASSOC
};

t_bit_field_assocs_data	fc_frametype_bfad = 
{
  &fc_frametype_bit_field,
  fc_frametype_assocs
};

t_bit_field	fc_mbz1_bit_field = 
{
  2,2
};

t_bit_field	fc_mbz2_bit_field = 
{
  3,3
};

t_bit_field	fc_attention_bit_field = 
{
  4,7
};

t_assoc				fc_attention_assocs[] = 
{
  {"express_buffer",		(VOID_PTR)1},
  {"beacon",			(VOID_PTR)2},
  {"claim_token",		(VOID_PTR)3},
  {"ring_purge",		(VOID_PTR)4},
  {"active_monitor_present",	(VOID_PTR)5},
  {"standby_monitor_present",	(VOID_PTR)6},
  NULL_ASSOC
};

t_bit_field_assocs_data		fc_attention_bfad = 
{
  &fc_attention_bit_field,
  fc_attention_assocs
};

t_bit_field	dhost_rii_bit_field =
{
  0,0
};	

t_assoc		dhost_rii_assocs[] = 
{
  {"-",		(VOID_PTR)0},
  {"RI",	(VOID_PTR)1},
  NULL_ASSOC
};

t_bit_field_assocs_data	dhost_rii_bfad = 
{
  &dhost_rii_bit_field,
  dhost_rii_assocs
};

t_bit_field	dhost_ig_bit_field = 
{
  1,1
};

t_assoc		dhost_ig_assocs[] = 
{
  {"group",	(VOID_PTR)0},
  {"individual",(VOID_PTR)1},
  NULL_ASSOC
};

t_bit_field_assocs_data	dhost_ig_bfad = 
{
  &dhost_ig_bit_field,
  dhost_ig_assocs
};

t_bit_field	shost_ig_bit_field =
{
  0,0
};	

t_assoc		shost_ig_assocs[] = 
{
  {"individual",(VOID_PTR)0},
  {"group",	(VOID_PTR)1},
  NULL_ASSOC
};

t_bit_field_assocs_data	shost_ig_bfad = 
{
  &shost_ig_bit_field,
  shost_ig_assocs
};

t_bit_field	shost_ul_bit_field = 
{
  1,1
};

t_assoc		shost_ul_assocs[] = 
{
  {"universally",(VOID_PTR)0},
  {"locally",	(VOID_PTR)1},
  NULL_ASSOC
};

t_bit_field_assocs_data	shost_ul_bfad = 
{
  &shost_ul_bit_field,
  shost_ul_assocs
};

int		tr_get_frametype(tr)
t_tr		*tr;
{
  t_u8		fc;
  t_u8		frametype;

  FBCOPY(&tr->fc,&fc,sizeof (fc)); /* alignment */
  bit_field_u8_get(&fc,
		   &frametype,
		   fc_frametype_bit_field.from,
		   fc_frametype_bit_field.to);
  return ((int)frametype);
}

t_field				tr_fields[] = 
{
  {"ac",	OFFSET(t_tr *,ac),	&u8_pat,		NULL},
  {"priority",	OFFSET(t_tr *,ac),     &u8bitfield_pat,&ac_priority_bit_field},
  {"token",	OFFSET(t_tr *,ac),        &u8bitfield_pat,&ac_token_bit_field},
  {"Token",	OFFSET(t_tr *,ac),        &u8bitfieldassoc_pat,&ac_token_bfad},
  {"monitor",	OFFSET(t_tr *,ac),      &u8bitfield_pat,&ac_monitor_bit_field},
  {"reservation",OFFSET(t_tr *,ac), &u8bitfield_pat,&ac_reservation_bit_field},
  {"fc",	OFFSET(t_tr *,fc),	&u8_pat,		NULL},
  {"frametype",	OFFSET(t_tr *,fc),    &u8bitfield_pat,&fc_frametype_bit_field},
  {"Frametype",	OFFSET(t_tr *,fc),    &u8bitfieldassoc_pat,&fc_frametype_bfad},
  {"mbz1",	OFFSET(t_tr *,fc),         &u8bitfield_pat,&fc_mbz1_bit_field},
  {"mbz2",	OFFSET(t_tr *,fc),         &u8bitfield_pat,&fc_mbz2_bit_field},
  {"attention",	OFFSET(t_tr *,fc),    &u8bitfield_pat,&fc_attention_bit_field},
  {"Attention",	OFFSET(t_tr *,fc),    &u8bitfieldassoc_pat,&fc_attention_bfad},
  {"dhost",	OFFSET(t_tr *,dhost),	&buf_pat,		(VOID_PTR)6},
  {"Drii",	OFFSET(t_tr *,dhost),	 &u8bitfieldassoc_pat,&dhost_rii_bfad},
  {"Dig",	OFFSET(t_tr *,dhost),     &u8bitfieldassoc_pat,&dhost_ig_bfad},
  {"shost",	OFFSET(t_tr *,shost),	&buf_pat,		(VOID_PTR)6},
  {"Sig",	OFFSET(t_tr *,shost),	  &u8bitfieldassoc_pat,&shost_ig_bfad},
  {"Sul",	OFFSET(t_tr *,shost),	  &u8bitfieldassoc_pat,&shost_ul_bfad},
  NULL_FIELD
};

char				*tr_itmpl = "\n\
<table _name=tr[%i%] width=100%%%% bgcolor=\"%%trColor%%\">\n\
<tr>\n\
<td align=center width=37%%%%>\n\
<a href=\"set(tr[%i%].priority)\">%%tr[%i%].priority%%</a>\n\
</td>\n\
<td align=center width=12%%%%>\n\
<a href=\"set(tr[%i%].Token)\">%%tr[%i%].Token%%</a>\n\
</td>\n\
<td align=center width=12%%%%>\n\
<a href=\"set(tr[%i%].monitor)\">%%tr[%i%].monitor%%</a>\n\
</td>\n\
<td align=center width=37%%%%>\n\
<a href=\"set(tr[%i%].reservation)\">%%tr[%i%].reservation%%</a>\n\
</td>\n\
</tr>\n\
<tr>\n\
<td align=center width=25%%%%>\n\
<a href=\"set(tr[%i%].Frametype)\">%%tr[%i%].Frametype%%</a>\n\
(<a href=\"set(tr[%i%].frametype)\">%%tr[%i%].frametype%%</a>)\n\
</td>\n\
<td align=center width=12%%%%>\n\
<a href=\"set(tr[%i%].mbz1)\">%%tr[%i%].mbz1%%</a>\n\
</td>\n\
<td align=center width=12%%%%>\n\
<a href=\"set(tr[%i%].mbz2)\">%%tr[%i%].mbz2%%</a>\n\
</td>\n\
<td align=center width=50%%%%>\n\
<a href=\"set(tr[%i%].Attention)\">%%tr[%i%].Attention%%</a>\n\
(<a href=\"set(tr[%i%].attention)\">%%tr[%i%].attention%%</a>)\n\
</td>\n\
</tr>\n\
<tr>\n\
<td align=center width=100%%%%>\n\
<a href=\"set(tr[%i%].Drii)\">%%tr[%i%].Drii%%</a> \n\
<a href=\"set(tr[%i%].Dig)\">%%tr[%i%].Dig%%</a>\n\
<code>\n\
(<a href=\"set(tr[%i%].dhost)\">%%tr[%i%].dhost%%</a>)\n\
</code>\n\
</td>\n\
</tr>\n\
<tr>\n\
<td align=center width=100%%%%>\n\
<a href=\"set(tr[%i%].Sig)\">%%tr[%i%].Sig%%</a> \n\
<a href=\"set(tr[%i%].Sul)\">%%tr[%i%].Sul%%</a>\n\
<code>\n\
(<a href=\"set(tr[%i%].shost)\">%%tr[%i%].shost%%</a>)\n\
</code>\n\
</td>\n\
</tr>\n\
</table>\n\
<br>\n\
";

int	tr_chan;

PAT_NAME_GENERIC(tr_pat_name,
		 (VOID_PTR)&tr_chan,
		 "tr")

PAT_GET_FIELD_GENERIC(tr_pat_get_field,
		      tr_fields)

PAT_SET_FIELD_GENERIC(tr_pat_set_field,
		      tr_fields)

PAT_GET_FIELDS_GENERIC(tr_pat_get_fields,
		       tr_fields)

PAT_GET_FIELD_PAT_GENERIC(tr_pat_get_field_pat,
			  tr_fields)

PAT_GET_TMPL_GENERIC(tr_pat_get_tmpl,
		     (VOID_PTR)&tr_chan,
		     tr_itmpl)

PAT_OFF_GENERIC(tr_pat_off,
		TR_HLEN)


PAT_SUB_DECL(tr_pat_sub)
{
  t_tr		*tr;
  
  PAT_TR_CHECK(tr,buf,len);
  switch (tr_get_frametype(tr))
    {
    case TR_FRAMETYPE_LLC:
      (*pat_return) = &llc_pat;
      return (0);
    };
  (*pat_return) = &data_pat;
  return (0);
}

t_pat				tr_pat = 
{
  tr_pat_name,			/* t_pat_name_proc		*/
  tr_pat_off,			/* t_pat_off_proc		*/
  tr_pat_sub,			/* t_pat_sub_proc		*/
  NULL,				/* t_pat_sum_proc		*/
  tr_pat_get_field,		/* t_pat_get_field_proc		*/
  tr_pat_set_field,		/* t_pat_set_field_proc		*/
  tr_pat_get_fields,		/* t_pat_get_fields_proc	*/
  tr_pat_get_tmpl,		/* t_pat_get_tmpl_proc		*/
  NULL,				/* t_pat_get_tmpl2_proc		*/
  NULL,				/* t_pat_has_opt_proc		*/
  NULL,				/* t_pat_adapt_len_proc		*/
  tr_pat_get_field_pat,		/* t_pat_get_field_pat_proc	*/
  NULL,				/* t_pat_extract_proc		*/
  NULL,				/* t_pat_insert_proc		*/
  NULL,				/* t_pat_get_choices_proc	*/
};
