
/******************************************************************************
**
**  This program is free software; you can redistribute it and/or
**  modify it, however, you cannot sell it.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
**
**  You should have received a copy of the license attached to the
**  use of this software.  If not, visit www.shmoo.com/osiris for
**  details.
**
******************************************************************************/

/*****************************************************************************
**
**  File:    message.h
**  Date:    February 17, 2002
**  
**  Author:  Brian Wotring
**  Purpose: message handling routines.
**
******************************************************************************/

#ifndef MESSAGE_H_
#define MESSAGE_H_


extern int SYSLOG_PRIORITY;

/*****************************************************************************

  messages consist of a header and a variable length body.  The format for
  the six byte header is as follows:
  
  +----+----+----+----+----+----+-----------
  | TYPE    | LENGTH  | SEQ     |     DATA.....   
  +----+----+----+----+----+----+-------------
  
  type is a two byte message code, length is the length of the data.

******************************************************************************/


#define MAX_MESSAGE_DATA_SIZE    	  ( 1024 - MESSAGE_HEADER_SIZE )
#define MESSAGE_HEADER_SIZE			  6

#define GET_TOTAL_MESSAGE_SIZE(m)     ( MESSAGE_HEADER_SIZE +\
                                        GET_MESSAGE_LENGTH(m) )

/* message types. */

#define MESSAGE_TYPE_UNKNOWN			0xFF
#define MESSAGE_TYPE_ERROR			    0xEF

#define MESSAGE_TYPE_SUCCESS			0xEE

#define MESSAGE_TYPE_START_SCAN			0x01
#define MESSAGE_TYPE_STOP_SCAN			0x02

#define MESSAGE_TYPE_STATUS_REQUEST		0x03
#define MESSAGE_TYPE_STATUS_RESPONSE    0x04

#define MESSAGE_TYPE_CONFIG_DATA		0x05
#define MESSAGE_TYPE_SCAN_DATA			0x06
#define MESSAGE_TYPE_DB_DATA			0x07

#define MESSAGE_TYPE_CONFIG_DATA_FIRST	0x08
#define MESSAGE_TYPE_CONFIG_DATA_LAST	0x09

#define MESSAGE_TYPE_SCAN_DATA_FIRST	0x0A
#define MESSAGE_TYPE_SCAN_DATA_LAST		0x0B

#define MESSAGE_TYPE_DB_DATA_FIRST		0x0C
#define MESSAGE_TYPE_DB_DATA_LAST		0x0D

/* control messages. */

#define MESSAGE_TYPE_CONTROL_REQUEST		0x0E

#define MESSAGE_TYPE_CONTROL_DATA       	0x0F
#define MESSAGE_TYPE_CONTROL_DATA_FIRST		0x10
#define MESSAGE_TYPE_CONTROL_DATA_LAST		0x11

#define MESSAGE_TYPE_DROP_CONFIG		    0x12
#define MESSAGE_TYPE_SESSION_KEY		    0x13

#define MESSAGE_TYPE_HTTP_DATA              0x14

/* pretty names for message types. */

#define MESSAGE_STRING_UNKNOWN			    "unknown"
#define MESSAGE_STRING_ERROR			    "error"

#define MESSAGE_STRING_SUCCESS			    "success"

#define MESSAGE_STRING_START_SCAN		    "start-scan"
#define MESSAGE_STRING_STOP_SCAN		    "stop-scan"

#define MESSAGE_STRING_STATUS_REQUEST		"status-request"
#define MESSAGE_STRING_STATUS_RESPONSE		"status-response"

#define MESSAGE_STRING_CONFIG_DATA		    "config-data"
#define MESSAGE_STRING_SCAN_DATA		    "scan-data"
#define MESSAGE_STRING_DB_DATA			    "db-data"

#define MESSAGE_STRING_CONFIG_DATA_FIRST	"config-data-first"
#define MESSAGE_STRING_CONFIG_DATA_LAST		"config-data-last"

#define MESSAGE_STRING_SCAN_DATA_FIRST		"scan-data-first"
#define MESSAGE_STRING_SCAN_DATA_LAST		"scan-data-last"

#define MESSAGE_STRING_DB_DATA_FIRST		"db-data-first"
#define MESSAGE_STRING_DB_DATA_LAST		    "db-data-last"

#define MESSAGE_STRING_CONTROL_REQUEST		"control-request"
#define MESSAGE_STRING_CONTROL_DATA		    "control-data"
#define MESSAGE_STRING_CONTROL_DATA_FIRST	"control-data-first"
#define MESSAGE_STRING_CONTROL_DATA_LAST	"control-data-last"

#define MESSAGE_STRING_DROP_CONFIG		    "drop-config"
#define MESSAGE_STRING_SESSION_KEY		    "session-key"


/* macros for setting/getting header information. */

#define GET_MESSAGE_TYPE(m)             ( m->header.type )
#define GET_MESSAGE_LENGTH(m)			( m->header.length )
#define GET_MESSAGE_SEQUENCE(m)			( m->header.sequence )

#define SET_MESSAGE_TYPE(m,t)			( m->header.type =  t )
#define SET_MESSAGE_LENGTH(m,l)			( m->header.length = l )
#define SET_MESSAGE_SEQUENCE(m,s)		( m->header.sequence = s )


/* generic messages. */


/* used to cast payload into specified type. */

#define MESSAGE_TO_TYPE(m,t)       		( (t)( (m)->data ) )



typedef struct MESSAGE_HEADER
{
    osi_uint16 type;
    osi_uint16 length;
    osi_uint16 sequence;

} MESSAGE_HEADER;


typedef struct MESSAGE
{
    MESSAGE_HEADER header;
    unsigned char data[MAX_MESSAGE_DATA_SIZE];

} MESSAGE;




/* function prototypes. */

MESSAGE * initialize_message( MESSAGE *message, osi_uint16 type );

int message_set_payload( MESSAGE *message, void *payload, int payload_length,
                         int sequence );

int osi_write_error_message( osi_uint64 type, const char *error_message,
                             int connection_socket );

int osi_write_success_message( int connection_socket );

int osi_ssl_write_error_message( osi_uint64 type, const char *error_message,
                                 SSL *ssl );

int osi_ssl_write_success_message( SSL *ssl );

/* basic message read/write methods. */

int osi_read_message( MESSAGE *message, int connection_socket );

int read_message_header_from_socket( MESSAGE_HEADER *header,
                                     int connection_socket );

int read_message_body_from_socket( MESSAGE *message, int connection_socket );

int osi_write_message( MESSAGE *message, int connection_socket );

/* basic message read/write with SSL methods. */

int osi_ssl_read_message( MESSAGE *message, SSL *ssl );
int osi_ssl_read_message_header( MESSAGE_HEADER *header, SSL *ssl );
int osi_ssl_read_message_body( MESSAGE *message, SSL *ssl );
int osi_ssl_read_http_message( MESSAGE *message, SSL *ssl );

int osi_ssl_write_message( MESSAGE *message, SSL *ssl );

/* misc. */

int message_header_is_valid( MESSAGE_HEADER *header );
char * get_name_for_message_type( int type );

void dump_message( MESSAGE *message );
void dump_message_header( MESSAGE *message );

#endif


