/*
    Copyright 2000 (c) by Claudio Jeker,
    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/NetModulesDef.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 _NETMODULESDEF_H_
#define _NETMODULESDEF_H_

/* LSB = 0 */
/* chainKeys: (16 bit short)
 *  15-11: location
 *     10: RFU (reserved for future use)
 *   9- 0: protocol type
 */
/* NetModuleType: (32 bit long)
 *     31: protocol modul
 *     30: in front/!at end
 *  29-26: RFU
 *  25-16: protocol type
 *  15- 0: unique module type
 */

/* protocol type only 10-bits 0x0 and 0x3FF are reserved */
/* the MSB chooses direction up <-> down so only 0x01 to 0x1FE can be used */
#define DOWN(x)					(1<<9 | x)

/* UP: incoming, to user process */
#define NET_PROTO_ETHERNET_UP	0x01
#define NET_PROTO_PPP_UP		0x02
#define NET_PROTO_IPv4_UP		0x03
#define NET_PROTO_IPv6_UP		0x04
#define NET_PROTO_ARP_REPLY		0x05 /* arp does not have a UP but a REPLY */
#define NET_PROTO_ICMP_UP		0x06
#define NET_PROTO_ICMP6_UP		0x09
#define NET_PROTO_UDP_UP		0x07
#define NET_PROTO_TCP_UP		0x08

/* special chains */
#define NET_PROTO_ETHERNET_BRIDGE	0x1F1
#define NET_PROTO_IP_FORWARDING		0x1F2

/* DOWN: outgoing, to the network */
#define NET_PROTO_ETHERNET_DOWN	DOWN(NET_PROTO_ETHERNET_UP)
#define NET_PROTO_PPP_DOWN		DOWN(NET_PROTO_PPP_UP)
#define NET_PROTO_IPv4_DOWN		DOWN(NET_PROTO_IPv4_UP)
#define NET_PROTO_IPv6_DOWN		DOWN(NET_PROTO_IPv6_UP)
#define NET_PROTO_ARP_DOWN		DOWN(NET_PROTO_ARP_REPLY)
#define NET_PROTO_ICMP_DOWN		DOWN(NET_PROTO_ICMP_UP)
#define NET_PROTO_ICMP6_DOWN		DOWN(NET_PROTO_ICMP6_UP)
#define NET_PROTO_UDP_DOWN		DOWN(NET_PROTO_UDP_UP)
#define NET_PROTO_TCP_DOWN		DOWN(NET_PROTO_TCP_UP)


/* chain location */
/* there are 32 posibilities, the names should represent the osi layers
 * again 0x0 and 0x1F should not be used also loops should be omitted */
/* We start with six distributors:
             IN
		  /   |    \
      OSI_23  |  OSI_43
	     |   \|/    |
		 |   /|\    |
      OSI_34  |  OSI_32
	      \   |    /
		     OUT
*/
/* We added only those chains that were reasonable for us CJ/BL */
/*       FROM_TO_CHAIN */
#define  IN_OUT_CHAIN 0x01
/* UP */
#define  IN_OSI_23_CHAIN 0x02
#define  IN_OSI_34_CHAIN 0x03
/* DOWN */
#define  IN_OSI_43_CHAIN 0x04
#define  IN_OSI_32_CHAIN 0x05

#define  OSI_23_OSI_34_CHAIN 0x06
#define  OSI_23_OSI_32_CHAIN 0x07
#define  OSI_23_OUT_CHAIN 0x08

#define  OSI_43_OSI_32_CHAIN 0x09
#define  OSI_43_OSI_34_CHAIN 0x0a
#define  OSI_43_OUT_CHAIN 0x0b

#define  OSI_32_OSI_23_CHAIN 0x0c
#define  OSI_32_OUT_CHAIN 0x0d

#define  OSI_34_OSI_43_CHAIN 0x0e
#define  OSI_34_OUT_CHAIN 0x0f

/* chain definitions, used in NetInit.c to init the distributors */
/* chainKeys: (16 bit short)
 *  15-11: location
 *     10: RFU (reserved for future use)
 *   9- 0: protocol type
 */
#define CHAIN(location,proto) ( ((location & 0x1F)<<11 ) | (proto & 0x3FF) )

#define ETHERNET_UP_CHAIN \
	CHAIN(IN_OSI_23_CHAIN, NET_PROTO_ETHERNET_UP)
#define ETHERNET_DOWN_CHAIN \
	CHAIN(OSI_32_OUT_CHAIN, NET_PROTO_ETHERNET_DOWN)

#define ARP_REPLY_CHAIN \
	CHAIN(OSI_23_OSI_32_CHAIN, NET_PROTO_ARP_REPLY)
#define ARP_SEND_CHAIN \
	CHAIN(IN_OSI_32_CHAIN, NET_PROTO_ARP_DOWN)

#define IPv4_UP_CHAIN \
	CHAIN(OSI_23_OSI_34_CHAIN, NET_PROTO_IPv4_UP)
#define IPv4_DOWN_CHAIN \
	CHAIN(OSI_43_OSI_32_CHAIN, NET_PROTO_IPv4_DOWN)

#define IPv6_UP_CHAIN \
	CHAIN(OSI_23_OSI_34_CHAIN, NET_PROTO_IPv6_UP)
#define IPv6_DOWN_CHAIN \
	CHAIN(OSI_43_OSI_32_CHAIN, NET_PROTO_IPv6_DOWN)

#define UDP_UP_CHAIN \
	CHAIN(OSI_34_OUT_CHAIN, NET_PROTO_UDP_UP)
#define UDP_DOWN_CHAIN \
	CHAIN(IN_OSI_43_CHAIN, NET_PROTO_UDP_DOWN)

#define TCP_UP_CHAIN \
	CHAIN(OSI_34_OUT_CHAIN, NET_PROTO_TCP_UP)
#define TCP_DOWN_CHAIN \
	CHAIN(IN_OSI_43_CHAIN, NET_PROTO_TCP_DOWN)

#define ICMP_UP_CHAIN \
	CHAIN(OSI_34_OUT_CHAIN, NET_PROTO_ICMP_UP)
#define ICMP_DOWN_CHAIN \
	CHAIN(IN_OSI_43_CHAIN, NET_PROTO_ICMP_DOWN)

#define ICMP6_UP_CHAIN \
	CHAIN(OSI_34_OUT_CHAIN, NET_PROTO_ICMP6_UP)
#define ICMP6_DOWN_CHAIN \
	CHAIN(IN_OSI_43_CHAIN, NET_PROTO_ICMP6_DOWN)

#define ETHERNET_BRIDGE_CHAIN \
	CHAIN(OSI_23_OSI_32_CHAIN, NET_PROTO_ETHERNET_BRIDGE)
#define IP_FORWARDING_CHAIN \
	CHAIN(OSI_34_OSI_43_CHAIN, NET_PROTO_IP_FORWARDING)

/* module definitions used in NetModuleRegistry.c to register the Modules */
/* NetModuleType: (32 bit long)
 *     31: protocol modul
 *     30: in front/!at end
 *  29-26: RFU
 *  25-16: protocol type
 *  15- 0: unique module type
 */
#define MODULETYPE(pm,front,proto,id) \
	(((pm & 1)<<31) | ((front & 1)<<30) | ((proto & 0x3FF)<<16) | (id & 0xFFFF))

/* first the well known modules types (acctually they are not used) */
#define MODULE_LOADER_TYPE			MODULETYPE(0, 0, 0, 0x10AD)
#define MODULE_LOOKUP_TYPE			MODULETYPE(0, 0, 0, 0x1004)
#define IN_DISTRIBUTOR_TYPE			MODULETYPE(0, 0, 0, 0x00D1)
#define OUT_DISTRIBUTOR_TYPE		MODULETYPE(0, 0, 0, 0xFFD1)
#define OSI_23_DISTRIBUTOR_TYPE		MODULETYPE(0, 0, 0, 0x23D1)
#define OSI_34_DISTRIBUTOR_TYPE		MODULETYPE(0, 0, 0, 0x34D1)
#define OSI_43_DISTRIBUTOR_TYPE		MODULETYPE(0, 0, 0, 0x43D1)
#define OSI_32_DISTRIBUTOR_TYPE		MODULETYPE(0, 0, 0, 0x32D1)

/* now the generic modules (defined in NetModulesRegistr.c) */
#define NULL_MODULE_TYPE		MODULETYPE(0, 0, 0, 0x0001)
/* ethernet */
#define ETHERNET_MODULE_DOWN_TYPE \
						MODULETYPE(1, 0, NET_PROTO_ETHERNET_DOWN, 0x0001)
#define ETHERNET_MODULE_UP_TYPE	\
						MODULETYPE(1, 1, NET_PROTO_ETHERNET_UP, 0x0001)
/* IPv4 */
#define IPv4_MODULE_DOWN_TYPE	MODULETYPE(1, 0, NET_PROTO_IPv4_DOWN, 0x0001)
#define IPv4_MODULE_UP_TYPE	MODULETYPE(1, 1, NET_PROTO_IPv4_UP, 0x0001)

/* IPv6 */
#define IPv6_MODULE_DOWN_TYPE	MODULETYPE(1, 0, NET_PROTO_IPv6_DOWN, 0x0001)
#define IPv6_MODULE_UP_TYPE	MODULETYPE(1, 1, NET_PROTO_IPv6_UP, 0x0001)


/* IP Forward */
#define IP_FORWARD_MODULE_TYPE	MODULETYPE(0, 0, NET_PROTO_IPv4_UP, 0x0002)
#define IP_FORWARD_PROTO_TYPE	MODULETYPE(1, 1, NET_PROTO_IP_FORWARDING,0x0001)
/* UDP */
#define UDP_MODULE_DOWN_TYPE	MODULETYPE(1, 0, NET_PROTO_UDP_DOWN, 0x0001)
#define UDP_MODULE_UP_TYPE		MODULETYPE(1, 1, NET_PROTO_UDP_UP, 0x0001)
#define UDPPCB_MODULE_DOWN_TYPE	MODULETYPE(0, 0, NET_PROTO_UDP_DOWN, 0x0002)
#define UDPPCB_MODULE_UP_TYPE	MODULETYPE(0, 1, NET_PROTO_UDP_UP, 0x0002)
/* ICMP */
#define ICMP_MODULE_DOWN_TYPE	MODULETYPE(1, 0, NET_PROTO_ICMP_DOWN, 0x0001)
#define ICMP_MODULE_UP_TYPE		MODULETYPE(1, 1, NET_PROTO_ICMP_UP, 0x0001)
/* ICMP6 */
#define ICMP6_MODULE_DOWN_TYPE	MODULETYPE(1, 0, NET_PROTO_ICMP6_DOWN, 0x0001)
#define ICMP6_MODULE_UP_TYPE	MODULETYPE(1, 1, NET_PROTO_ICMP6_UP, 0x0001)
/* ARP */
#define ARP_MODULE_SEND_TYPE	MODULETYPE(1, 0, NET_PROTO_ARP_DOWN, 0x0001)
#define ARP_MODULE_RECV_TYPE	MODULETYPE(1, 1, NET_PROTO_ARP_REPLY, 0x0001)
/* every OSI 2 protocol with arp capabilities needs such a module for
   arp lookups */
#define ETH_ARP_MODULE_TYPE 	\
						MODULETYPE(0, 1, NET_PROTO_ETHERNET_DOWN, 0x000A)

/* other important module types */
/* the module lookup and loader are so special, they have a fix ModuleId */
#define NET_MODULE_LOOKUP_ID		-2
#define NET_MODULE_LOADER_ID		-3
#define NET_MODULE_LOOKUP_THREAD	1
#define NET_MODULE_LOADER_THREAD	2
/* also the in distributor has to be known */
#define NET_MODULE_IN_DISTRIBUTOR_ID	-4

#endif
