/**
 * ============================================================================
 * = COPYRIGHT
 *              INTEL CORPORATION PROPRIETARY INFORMATION
 *   This software is supplied under the terms of a license agreement or
 *   nondisclosure agreement with Intel Corporation and may not be copied 
 *   or disclosed except in accordance with the terms in that agreement.
 *      Copyright (C) 2002 Intel Corporation. All rights reserved.
 *
 * = PRODUCT
 *      Intel(r) IXA SDK 3.0 for the IXP2000 Network Processor, Release 5
 *
 *       
 *
 * = MODULE
 *      ICMP module
 *
 * = FILENAME
 *      icmp.h
 *
 * = DESCRIPTION
 *    
 *    This file contains the definition of ICMP message building
 *    functions. ICMP messages supported are ICMP parameter problem
 *    message, ICMP destination unreachable message, ICMP time
 *    exceeded error message and ICMP redirect message. This file
 *    also contains internal functions for building ICMP messages
 *    and queueing these into ICMP queue.     
 *
 *
 * 
 * = CHANGE HISTORY
 *
 * ============================================================================
 * $Id: icmp.h,v 1.7 2003/11/04 21:38:34 rranjeet Exp $
 */

#if !defined(__ICMP_H__)
#define __ICMP_H__


#if defined(__cplusplus)
extern "C"
{
#endif /* end defined(__cplusplus) */

/**
 * Preprocessor symbol and macro definitions.
 */


/*** icmp_queue.h has declaration of queue related parameters ***/
#include "icmp_queue.h"


/**
 * Type definitions.
 */
#define IX_CC_IPV4_ICMP_MIN_SLEEP_TIME 1
#define IX_CC_IPV4_ICMP_MAX_SLEEP_TIME 32
#define IX_CC_IPV4_ICMP_DEFAULT_SLEEP_TIME 1
#define IX_CC_IPV4_ICMP_DUMP_MSG_SIZE 32
#define IX_CC_IPV4_IP_HDR_PAYLOAD_LIMIT 576

#define _IX_CC_IPV4_ICMPQUEUE_LINE_SIZE 50
#define _IX_CC_IPV4_ICMPQUEUE_TITLE_STRING  "Type Code Checksum \n"
#define _IX_CC_IPV4_ICMPQUEUE_TITLE_SIZE sizeof(_IX_CC_IPV4_ICMPQUEUE_TITLE_STRING)
#define _IX_CC_IPV4_ICMPQUEUE_TERM_STRING "\n"
#define _IX_CC_IPV4_ICMPQUEUE_TERM_SIZE sizeof(_IX_CC_IPV4_ICMPQUEUE_TERM_STRING)
/**
 * Prototypes for interface functions.
 */

/**
 * NAME: _ix_cc_ipv4_icmp_init
 *
 * DESCRIPTION: This routine initializes member variables to d
 *              default state. This function initializes 
 *              g_IcmpQueueDepth to IX_CC_IPV4_ICMPQ_MAXSIZE(8),
 *              g_IcmpSleepTime to 1 second and g_IcmpQueueDrain
 *              to IX_CC_IPV4_ICMPQ_MAXSIZE. This function also
 *              calls initialization function for queue
 * 
 * @Param:  - IN None
 *            
 * @Param:  - INOUT  - None
 * @Param:  - OUT - None  
 *
 *
 */

void _ix_cc_ipv4_icmp_init(void);

/**
 * NAME: ix_cc_ipv4_icmp_param_problem
 *
 * DESCRIPTION: This function will build a complete ICMP parameter problem
 *              error message for the packet passed in the buffer handle.  
 * 
 * @Param:  - IN arg_hBuffer - the buffer handle containing the packet that is 
 *		causing the ICMP message to be generated 
 *            IN arg_Param - Byte offset in the IP header that is
 * 			causing the error. This parameter is in 
 *                      host order
 * @Param:  - INOUT  - None
 * @Param:  - OUT - None  
 *
 *
 */

ix_error _ix_cc_ipv4_icmp_param_problem(
			ix_buffer_handle arg_hBuffer, 
			ix_uint32 arg_Param 
			);

/**
 * NAME: _ix_cc_ipv4_icmp_dest_unreachable
 *
 * DESCRIPTION: This function will build a complete ICMP Destination
 *              Unreachable error message for the packet passed in
 *              the buffer handle.  
 * 
 * @Param:  - IN arg_hBuffer - the buffer handle containing the packet
 *             that is causing the ICMP message to be generated
 *  
 *            IN arg_Reason - the reason that the destination is
 *               unreachable.For different values for this field,
 *               refer to header_defs.h file
 *
 *            IN arg_Param - the data for the parameter field/extra field of
 *            the ICMP header. Generally, set to 0. It is in host byte
 *            order. When building the message and sending it out, it is
 *            converted to network byte order
 *
 * @Param:  - INOUT  - None
 * @Param:  - OUT - None  
 *
 * @Return: IX_SUCCESS if successful or a valid ix_error token for failure.
 *          
 */
ix_error _ix_cc_ipv4_icmp_dest_unreachable( 
				ix_buffer_handle arg_hBuffer,
				ix_uint8 arg_Reason, 
				ix_uint32 arg_Param);


/**
 * NAME: _ix_cc_ipv4_icmp_redirect
 *
 * DESCRIPTION: This function will build a complete ICMP redirect error
 *		message for the packet passed in the buffer handle.  
 * 
 * @Param:  - IN arg_buffer_handle - the buffer handle containing the packet
 *           that is causing the ICMP message to be generated
 * 
 *            IN arg_Gateway - the address of the gateway to which the traffic
 *            for the network specified in the IP destination address of
 *            the original datagram's data should be sent. This 
 *	      parameter is expected in host byte order. When building the
 *            the message and sending it out, it is converted to
 *            network byte order
 *
 * @Param:  - INOUT  - None
 * @Param:  - OUT - None  
 *
 * @Return: IX_SUCCESS if successful or a valid ix_error token for failure.
 */
ix_error _ix_cc_ipv4_icmp_redirect( 
			ix_buffer_handle arg_hBuffer, 
			ix_uint32 arg_Gateway 
			);

/**
 * NAME: ix_cc_ipv4_icmp_time_exceeded
 *
 * DESCRIPTION: This function will build a complete ICMP time exceeded error
 *		message for the packet passed in the buffer handle.  
 * 
 * @Param:  - IN arg_hBuffer - the buffer handle containing the packet that
 *		 is causing the ICMP message to be generated 
 *           
 *
 * @Param:  - INOUT  - None
 * @Param:  - OUT - None  
 *
 * @Return: IX_SUCCESS if successful or a valid ix_error token for failure.
 */
ix_error _ix_cc_ipv4_icmp_time_exceeded( 
				ix_buffer_handle arg_hBuffer 
				);

/*
* The rest of header file contains definition of APIs used
*     by above defined functions 
*/

/**
 * NAME: _ix_cc_ipv4_icmp_print_message
 *
 * DESCRIPTION: This function prints the header and the contents of 
 *              the ICMP payload
 *		 
 * 
 * @Param:  - IN arg_pMessage - the byte array containing an ICMP message,
 *                              that is,an ICMP header and its payload
 *		 arg_Size - the number of bytes in the ICMP message 
 *           
 *
 * @Param:  - INOUT  - None
 * @Param:  - OUT - None  
 *
 * @Return: None
 */
void _ix_cc_ipv4_icmp_print_message( 
			const ix_uint8 *arg_pMessage, 
			ix_uint32 arg_Size 
			);


/**
 * NAME: _ix_cc_ipv4_icmp_dump_message
 *
 * DESCRIPTION: This function prints the ICMP header 
 *  into a string buffer
 * 
 * @Param:  - IN arg_pMessage - the byte array containing an ICMP message,
 *		 that is, an ICMP header 
 *	      IN arg_MessageSize - the number of bytes in the ICMP message
 *            IN   arg_BufferSize - the size of buffer which will get a dump
 *               of ICMP header
 *       
 *
 * @Param:  - INOUT  - None
 * @Param:  - OUT - arg_pBuffer - the string buffer where the header
 * 		is printed
 *
 * @Return: IX_SUCCESS if successful or a valid error token on failure
 */
ix_error _ix_cc_ipv4_icmp_dump_message(const ix_uint8 *arg_pMessage,
                                    ix_uint32 arg_MessageSize,
                                    ix_uint32 arg_BufferSize,
                                    ix_uint8 *arg_pBuffer
                                    );




/**
 * NAME: _ix_cc_ipv4_icmp_build_message
 *
 * DESCRIPTION: This function builds a complete ICMP message and queues it so  
 *	        it can be sent. Note that the enqueue operation may fail due to
 *		queue being full. In that case, the ICMP message will not be 
 *		sent and the error packet will simply be dropped
 *		When forming the icmp message, all data is filled up in
 *              network byte order
 * 
 * @Param:  - IN - arg_Type - the type field for the ICMP header
 *            IN - arg_Code - the code field for the ICMP header 
 *	      IN - arg_Param - the data for the parameter field of the header
 *			(ie. the gateway address for redirect).
 *                       This parameter is in host byte order
 *		   arg_hBuffer - the buffer containing the IP packet
 *			 causing error
 *                 arg_SendMsg - This value indicates if ICMP message has to 
 *                                be sent.
 * @Param:  - INOUT  - None
 * @Param:  - OUT 
 *
 * @Return: IX_SUCCESS if successful or a valid ix_error for failure
 */
ix_error _ix_cc_ipv4_icmp_build_message( 
				ix_uint8 arg_Type, 
				ix_uint8 arg_Code, 
				ix_uint32 arg_Param,
				ix_uint32 arg_SendMsg, 
				ix_buffer_handle arg_hBuffer 
				);


/**
 * NAME: _ix_cc_ipv4_icmp_copy_payload
 *
 * DESCRIPTION: This function attempts to copy the number of bytes
 *              specified in length plus icmp header length.
 * 
 * @Param:  - IN - arg_pSource -  byte array of data to copy
 *                 arg_Length -maximum number of bytes to copy 
 *		   
 *		   
 * @Param:  - INOUT  - None
 * @Param:  - OUT arg_pDest - byte array to copy data into 
 *
 * @Return: the number of bytes actually copied
 */
ix_uint32 _ix_cc_ipv4_icmp_copy_payload( 
				ix_uint8 *arg_pSource, 
				ix_uint8 *arg_pDest, 
				ix_uint32 arg_Length 
				);

/**
 * NAME: _ix_cc_ipv4_icmp_ok_to_send
 *
 * DESCRIPTION: This function verifies that the given packet can cause 
 *              an ICMP error message to be generated. RFC1812 states
 *              several rules (section 4.3.2.7)
 *		for when a packet must generate an ICMP error message. 
 *              This routine compares the error packet to those rules
 *              and determines if an ICMP error
 *		message may or may not be sent.
 *		
 * 
 * @Param:  - IN - arg_hBuffer -  the buffer containing the packet
 *             to verify
 *		   
 *		   
 * @Param:  - INOUT  - None
 * @Param:  - OUT  - arg_pOkToSend =1 if packet may generate an ICMP error,
 *                 0 otherwise 
 *
 * @Return: IX_SUCCESS if successful or a valid ix_error token on failure
 */
ix_error _ix_cc_ipv4_icmp_ok_to_send(
                           ix_buffer_handle arg_hBuffer,
                           ix_uint32 *arg_pOkToSend
                           );

/**
 * NAME: _ix_cc_ipv4_icmp_queue_message
 *
 * DESCRIPTION: This function attempts to queue an ICMP error message so that
 *              it can be sent at a later time when the event fires to send the
 *              message from the  queue. There is no retry attempted if the
 *              queue is full. Instead the buffer is simply dropped. The queue
 *              (and its processing thread) are used to limit the number and 
 *              rate of ICMP error messages to comply
 *              with RFC 1812 section 4.3.2.8
 * 
 * @Param:  - IN - arg_hBuffer -  the buffer containing a valid ICMP error
 *                                message
 *		   
 *		   
 * @Param:  - INOUT  - None
 * @Param:  - OUT  - None 
 *
 * @Return: IX_SUCCESS if successful or a valid ix_error on failure
 */
ix_error _ix_cc_ipv4_icmp_queue_message( 
				ix_buffer_handle arg_hBuffer 
				);

/**
 * NAME: _ix_cc_ipv4_icmp_send_message
 *
 * DESCRIPTION: This function attempts to dequeue ICMP messages and
 *              send them to the destination. This is the ICMP
 *              queue processing loop. This is the event handler
 *              function that will be registered in the init 
 *              function of IPv4 Forwarder Core Component
 *		
 * @Param:  - IN - arg_pContext - Context returned by
 *                       ix_cci_cc_add_event_handler( ) function
 *		   
 *		   
 * @Param:  - INOUT  - None
 * @Param:  - OUT  - None 
 *
 * @Return: IX_SUCCESS if successful or a valid ix_error on failure
 */
ix_error _ix_cc_ipv4_icmp_send_message(void *arg_pContext);
				


/**
 * Exported variables.
 */
extern ix_uint16 g_IcmpQueueDepth;
extern ix_uint16 g_IcmpQueueDrain;
extern ix_uint16 g_IcmpSleepTime;



#if defined(__cplusplus)
}
#endif /* end defined(__cplusplus) */


#endif /* end !defined(__ICMP_H__) */


