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

t_assoc			ethertype_assocs[] = 
{
  {"pup",		(VOID_PTR)0x0200},
  {"ip",		(VOID_PTR)ETHERTYPE_IP},
  {"arp",		(VOID_PTR)ETHERTYPE_ARP},
  {"lat",		(VOID_PTR)0x6004},
  {"decnet",		(VOID_PTR)0x6003},
  {"moprc",		(VOID_PTR)0x6002},
  {"mopdl",		(VOID_PTR)0x6001},
  {"atalk",		(VOID_PTR)ETHERTYPE_ATALK},
  {"rarp",		(VOID_PTR)ETHERTYPE_RARP},
  {"loopback",		(VOID_PTR)0x9000},
  {NULL,		0},
};

VOID_FUNC		ether_set_shost(ether,ea)
t_ether			*ether;
t_ether_addr		*ea;
{
  FBCOPY(ea,ether->shost,sizeof (t_ether_addr)); 
}

VOID_FUNC		ether_get_shost(ether,ea)
t_ether			*ether;
t_ether_addr		*ea;
{
  FBCOPY(ether->shost,ea,sizeof (t_ether_addr));
}

VOID_FUNC		ether_set_dhost(ether,ea)
t_ether			*ether;
t_ether_addr		*ea;
{
  FBCOPY(ea,ether->dhost,sizeof (t_ether_addr)); 
}

VOID_FUNC		ether_get_dhost(ether,ea)
t_ether			*ether;
t_ether_addr		*ea;
{
  FBCOPY(ether->dhost,ea,sizeof (t_ether_addr));
}

VOID_FUNC		ether_set_type(ether,type)
t_ether			*ether;
int			type;
{
  safe_htons(type,&(ether->type));
}

int			ether_get_type(ether)
t_ether			*ether;
{
  return (safe_ntohs(&(ether->type)));
}

t_field				ether_fields[] = 
{
  {"dhost",	OFFSET(t_ether *,dhost),	&etheraddr_pat,		NULL},
  {"Dhost",	OFFSET(t_ether *,dhost),	&mac_pat,		NULL},
  {"shost",	OFFSET(t_ether *,shost),	&etheraddr_pat,		NULL},
  {"Shost",	OFFSET(t_ether *,shost),	&mac_pat,		NULL},
  {"type",	OFFSET(t_ether *,type),		&nu16_pat,		NULL},
  {"Type",	OFFSET(t_ether *,type),	     &nu16assoc_pat,ethertype_assocs},
  NULL_FIELD
};

char				*ether_itmpl = "\n\
<table _name=ether[%i%] width=100%%%% bgcolor=\"%%etherColor%%\">\n\
<tr>\n\
<td align=center width=40%%%%>\n\
<a href=\"set(ether[%i%].shost)\">%%ether[%i%].shost%%</a>\n\
<_tiny>\n\
<a href=\"set(ether[%i%].Shost)\">%%ether[%i%].Shost%%</a>\n\
</_tiny>\n\
</td>\n\
<td align=center width=40%%%%>\n\
<a href=\"set(ether[%i%].dhost)\">%%ether[%i%].dhost%%</a>\n\
<_tiny>\n\
<a href=\"set(ether[%i%].Dhost)\">%%ether[%i%].Dhost%%</a>\n\
</_tiny>\n\
</td>\n\
<td align=center width=20%%%%>\n\
<a href=\"set(ether[%i%].Type)\">%%ether[%i%].Type%%</a>\n\
(<a href=\"set(ether[%i%].type)\">%%ether[%i%].type%%</a>)\n\
</td>\n\
</tr>\n\
</table>\n\
<br>\n\
";

int	ether_chan;

PAT_NAME_GENERIC(ether_pat_name,
		 (VOID_PTR)&ether_chan,
		 "ether")

PAT_GET_FIELD_GENERIC(ether_pat_get_field,
		      ether_fields)

PAT_SET_FIELD_GENERIC(ether_pat_set_field,
		      ether_fields)

PAT_GET_FIELDS_GENERIC(ether_pat_get_fields,
		       ether_fields)

PAT_GET_FIELD_PAT_GENERIC(ether_pat_get_field_pat,
			  ether_fields)

PAT_GET_TMPL_GENERIC(ether_pat_get_tmpl,
		     (VOID_PTR)&ether_chan,
		     ether_itmpl)

PAT_OFF_GENERIC(ether_pat_off,
		ETHER_HLEN)


PAT_SUB_DECL(ether_pat_sub)
{
  t_ether		*ether;
  int			type;

  PAT_ETHER_CHECK(ether,buf,len);
  type = ether_get_type(ether);
  if (type <= 0x5dc)
    {
      (*pat_return) = &llc_pat;
      return (0);
    }
  switch (type)
    {
    case ETHERTYPE_IP:
      (*pat_return) = &ip_pat;
	return (0);
    case ETHERTYPE_ARP:
    case ETHERTYPE_RARP:
	(*pat_return) = &arp_pat;
	return (0);
    }
  (*pat_return) = &data_pat;
  return (0);
}

t_pat				ether_pat = 
{
  ether_pat_name,		/* t_pat_name_proc		*/
  ether_pat_off,		/* t_pat_off_proc		*/
  ether_pat_sub,		/* t_pat_sub_proc		*/
  NULL,				/* t_pat_sum_proc		*/
  ether_pat_get_field,		/* t_pat_get_field_proc		*/
  ether_pat_set_field,		/* t_pat_set_field_proc		*/
  ether_pat_get_fields,		/* t_pat_get_fields_proc	*/
  ether_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		*/
  ether_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	*/
};
