/*
    Copyright 2000 (c) by David Schweikert,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.
 
    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.
 
    For further information, please visit http://www.tik.ee.ethz.ch/~topsy
 
    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source: /home/ruf/cvs_Topsy/cvs/Topsy/Net/NetAttr.h,v $
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision: 2922 $
    Last Date of Change:   $Date: 2007-03-19 17:48:52 +0100 (Mon, 19 Mär 2007) $  by: $Author: baderma $
 
*/
#ifndef __NETATTR_H__
#define __NETATTR_H__

#include <NetBuf.h>

enum NetAttrKeys {
  NETATTR_UNKNOWN = 0, /* this is a placeholder, do not use it */

  /* OSI general types so the protocol does not have to know
   * the correct flags of the next protocol*/
  //-BL NETATTR_IF_TYPE,
  NETATTR_OSI_3_TYPE, NETATTR_OSI_4_TYPE,
  NETATTR_IN_TYPE, NETATTR_OSI_2_TYPE,
  /* NOTE: we use NETATTR_IN_TYPE instead since the InDistributor
   * handles OSI 2 & 4 and needs to know what to do */

  /* these types are used to set the protocol type and are used
   * by the distributors */
  NETATTR_TYPE_ETHERNET,
  NETATTR_TYPE_IPv4, NETATTR_TYPE_IPv6, NETATTR_TYPE_ARP,
  NETATTR_TYPE_UDP, NETATTR_TYPE_ICMP, NETATTR_TYPE_ICMP6, NETATTR_TYPE_TCP,
  NETATTR_TYPE_RAWIP,
  NETATTR_TYPE_UNKOWN,

  /* INTERFACE set by the device queue */
  NETATTR_IF_FROM, NETATTR_IF_TO, NETATTR_IF_MTU,

  /* BROADCAST */
  NETATTR_BROADCAST,

  /* ETHERNET */
  NETATTR_ETH_LOCAL_0, NETATTR_ETH_LOCAL_1, NETATTR_ETH_LOCAL_2,
  NETATTR_ETH_REMOTE_0,   NETATTR_ETH_REMOTE_1,   NETATTR_ETH_REMOTE_2,
  NETATTR_ETH_TYPE,
  NETATTR_ETH_MULTICAST,

  /* IPv4 */
  NETATTR_IP_LOCAL_0, NETATTR_IP_LOCAL_1,
  NETATTR_IP_LOCAL_2, NETATTR_IP_LOCAL_3,
  NETATTR_IP_REMOTE_0, NETATTR_IP_REMOTE_1,
  NETATTR_IP_REMOTE_2, NETATTR_IP_REMOTE_3,
  NETATTR_IP_VERSION,
  NETATTR_IP_TOS,      /* Type Of Service */
  NETATTR_IP_TTL,      /* Time To Live */
  NETATTR_IP_FRAG,     /* Fragment offset & flags*/
  NETATTR_IP_ID,       /* Fragment Identification */
  NETATTR_IP_DATALEN,  /* Total length (data) */
  NETATTR_IP_HEADLEN,  /* Length of header */
  NETATTR_IP_PROTOCOL,
  NETATTR_IP_CHECKSUM,
  NETATTR_IP_MTU,

  /* ARP */
  NETATTR_ARP_HW_TYPE,  /* HW: hardware (normally ethernet) */
  NETATTR_ARP_HW_LEN,
  NETATTR_ARP_PR_TYPE,  /* PR: protocol (normally IP) */
  NETATTR_ARP_PR_LEN,

  /* UDP */
  NETATTR_UDP_LOCAL,
  NETATTR_UDP_REMOTE,
  NETATTR_UDP_LENGTH,
  NETATTR_UDP_CHECKSUM,

  /* ICMP */
  NETATTR_ICMP_TYPE,
  NETATTR_ICMP_CODE,
  NETATTR_ICMP_CHECKSUM,

  /* TCP */
  NETATTR_TCP_LOCAL,
  NETATTR_TCP_REMOTE,
  NETATTR_OOBDATA,

  /* keys for distributing */
  NETATTR_DISTRIBUTOR_KEY,
  NETATTR_SENDTO_THREAD,
  NETATTR_SENDTO_THREADLOW,
  NETATTR_SENDTO_THREADHIGH,
  NETATTR_SENDTO_LOOP,

  NETATTR_SOCKET_THREADLOW,
  NETATTR_SOCKET_THREADHIGH,

  /* IPv6 */
  //NETATTR_IP6_VERSION,
  NETATTR_IP6_TRAFFICCLASS,
  NETATTR_IP6_FLOWLABEL_0,         // the 4 MSBs
  NETATTR_IP6_FLOWLABEL_1,         // the 16 LSBs
  NETATTR_IP6_PAYLOADLENGTH,
  NETATTR_IP6_NEXTHEADER,
  NETATTR_IP6_HOPLIMIT,


  NETATTR_IP6_SOURCEADDRESS_0, NETATTR_IP6_SOURCEADDRESS_1, NETATTR_IP6_SOURCEADDRESS_2,
  NETATTR_IP6_SOURCEADDRESS_3, NETATTR_IP6_SOURCEADDRESS_4, NETATTR_IP6_SOURCEADDRESS_5,
  NETATTR_IP6_SOURCEADDRESS_6, NETATTR_IP6_SOURCEADDRESS_7,
  NETATTR_IP6_DESTINATIONADDRESS_0, NETATTR_IP6_DESTINATIONADDRESS_1, NETATTR_IP6_DESTINATIONADDRESS_2,
  NETATTR_IP6_DESTINATIONADDRESS_3, NETATTR_IP6_DESTINATIONADDRESS_4, NETATTR_IP6_DESTINATIONADDRESS_5,
  NETATTR_IP6_DESTINATIONADDRESS_6, NETATTR_IP6_DESTINATIONADDRESS_7,
  NETATTR_IP6_MTU,

  /*      NETATTR_IP_HOPBYHOP_NEXTHEADER,       //temporary... length must be adapted if used...
          NETATTR_IP_HOPBYHOP_HEADER_EXT_LEN,
          NETATTR_IP_HOPBYHOP_OTPTIONS,
          
          NETATTR_IP_ROUTING_NEXTHEADER,                     
          NETATTR_IP_ROUTING_HEADER_EXT_LEN,
          NETATTR_IP_ROUTING_TYPE,
          NETATTR_IP_ROUTING_SEGMENTS_LEFT,
          NETATTR_IP_ROUTING_ADDRESSES, 
                    
          NETATTR_IP_FRAGMENT_NEXTHEADER,                    
          NETATTR_IP_FRAGMENT_HEADER_EXT_LEN,
          NETATTR_IP_FRAGMENT_RESERVED1,
          NETATTR_IP_FRAGMENT_FRAGMENTOFFSET,                 
          NETATTR_IP_FRAGMENT_RESERVED2,
          NETATTR_IP_FRAGMENT_M,
          NETATTR_IP_FRAGMENT_IDENTIFICATION,
   
          NETATTR_IP_DESTINATIONOPTION_NEXTHEADER,                     
          NETATTR_IP_DESTINATIONOPTION_HEADER_EXT_LEN,
          NETATTR_IP_DESTINATIONOPTION_OPTIONS,
  */
  /* ICMP6 */
  NETATTR_ICMP6_TYPE,
  NETATTR_ICMP6_CODE,
  NETATTR_ICMP6_CHECKSUM,
  NETATTR_ICMP6_IDENTIFIER,
  NETATTR_ICMP6_SEQUENCENUMBER,

  NETATTR_ICMP6_TARGETADDR0,
  NETATTR_ICMP6_TARGETADDR1,
  NETATTR_ICMP6_TARGETADDR2,
  NETATTR_ICMP6_TARGETADDR3,
  NETATTR_ICMP6_TARGETADDR4,
  NETATTR_ICMP6_TARGETADDR5,
  NETATTR_ICMP6_TARGETADDR6,
  NETATTR_ICMP6_TARGETADDR7,
  NETATTR_ICMP6_OPTIONTYPE,
  NETATTR_ICMP6_OPTIONLENGTH,
  NETATTR_ICMP6_LINKLAYERADDR0,
  NETATTR_ICMP6_LINKLAYERADDR1,
  NETATTR_ICMP6_LINKLAYERADDR2,
  NETATTR_ICMP6_LINKLAYERADDR3,
  NETATTR_ICMP6_LINKLAYERADDR4,
  NETATTR_ICMP6_LINKLAYERADDR5,

  NETATTR_LAST
};

typedef struct NetAttr_t
{
  unsigned short key;  /* ==0 -> not setted */
  unsigned short data;
}
NetAttr;

/* NETATTRS_* is for internal use */

#define NETATTRS_ATTRSIZE  sizeof(NetAttr)
#define NETATTRS_MAXATTRS  (63-sizeof(NetBufHdr)/NETATTRS_ATTRSIZE) /* Should exactly fill a

single 25x NetBuf... */
#define NETATTRS_SIZE      (NETATTRS_ATTRSIZE*NETATTRS_MAXATTRS)

typedef struct NetAttrs_t
{
  NetBufHdr netbufhdr;

  NetAttr attr[NETATTRS_MAXATTRS];
}
*NetAttrs;

int netattrNew(NetAttrs *a);
int netattrHash(unsigned short key);
int netattrFind(NetAttrs a, unsigned short key);
int netattrSet(NetAttrs a, unsigned short key, unsigned short data);
void netattrUnset(NetAttrs a, unsigned short key);
int netattrGet(NetAttrs a, unsigned short key, unsigned short *data);
int netattrCopy(NetAttrs target, NetAttrs source);
void netattrDebug(unsigned long family, char *title, NetAttrs a);
char* netattrGetName(unsigned short key);

#define NETATTR_FREE(x) netbufFree((NetBuf)x)

#endif /* __NETATTR_H__ */
