/*
 * simco_core.h
 *
 * Copyright (C) 2005, Ranch Networks, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * 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.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 * Author : Srivatsa Chivukula <srivatsa@ranchnetworks.com>
 *
 */

#ifndef _SIMCO_CORE_H_
#define _SIMCO_CORE_H_

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>

#define USE_SOCKETS
#include <openssl/e_os2.h>
#include <openssl/x509.h>
#define OPENSSL_NO_KRB5
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/rand.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <errno.h>
#include <unistd.h>

#include "s_apps.h"

#include "simco_client.h"

typedef struct ssl_st MCAgent;

extern int verify_depth;
extern int verify_error;

#define SET_REQUEST_SIZE 32*4

#define MAX_READ_SIZE 1024
#define MAX_CON 100
#define COMM_PORT 7626
#define NOTF_PORT 7627

typedef struct _MCAgentCon {
#ifndef NO_SSL
  SSL *sslcon;
#endif
  int sock;
  char *sbuf;
  int sbuf_offset;
  int inpool;
  int error;
} MCAgentCon;

extern MCAgentCon conn[];

extern int c_debug;

#ifndef NO_SSL
extern BIO *bio_err;
#else
#define BIO_printf fprintf
#define bio_err    stderr
#endif

#define CONF LHASH
/*
#ifdef SIGPIPE
#define do_pipe_sig()signal(SIGPIPE,SIG_IGN)
#else
#define do_pipe_sig()
#endif

#ifndef NO_SSL
#if defined(WIN32)
#    ifdef _O_BINARY
#      define apps_startup() \
_fmode=_O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); SSLeay_add_all_algorithms()
#    else
#      define apps_startup() \
_fmode=O_BINARY; do_pipe_sig(); CRYPTO_malloc_init(); SSLeay_add_all_algorithms()
#    endif
#  else
#    define apps_startup()do_pipe_sig(); SSLeay_add_all_algorithms();
#endif
#endif
*/

#define SIMCO_CHAR_INSERT(r,i,p)   *((char*)r+i)=(char)p;i+=1
#define SIMCO_SHORT_INSERT(r,i,p)  *((short*)r+i/2)=htons((short)p);i+=2
#define SIMCO_INT_INSERT(r,i,p)    *((int*)r+i/4)=htonl((int)p);i+=4
#define SIMCO_SIZE_INSERT(r,p)     *((short*)r+1)=htons((short)p)
#define SIMCO_STRING_INSERT(r,i,p) strcpy((char*)r+i,p);i+=strlen(p)

#ifdef WIN
#define get_last_socket_error()
#else
#define get_last_socket_error() errno
#endif

extern int rnMCAgentComm(MCAgentCon *con, char *cbuf, int cbuf_len, char **sbuf, int *sbuf_len);
extern int midcomAgentConnect(char *host, int port);
extern void midcomAgentDisconnect(MCAgentCon *conn);

extern void ip_ntoa(unsigned int addr, char *str);

extern void parseSIMCOPdu(simcoPacket_t *sp, char *pdu, int size);
extern int parseSIMCORuleList(char *pdu, int size, int **rules, int *numrules);
extern void parseSIMCOHeader(char *pdu, int size, int *status);

extern int rnMCAgentCommRead(MCAgentCon *con, char *sbuf, int *offset);
extern int rnMCAgentCommWrite(MCAgentCon *con, char *cbuf, int cbuf_len);

extern int makePingRequest(char *request);
extern int makeSessionEstablishRequest(char *request);
extern int makeSessionAuthenticateRequest(char *request, const char * str);
extern int makeSessionTerminateRequest(char *request);
extern int makePolicyReserveRuleRequest(char *request, const simcoPacket_t *sp);
extern int makePolicyEnableRuleRequest(char *request, const simcoPacket_t *sp);
extern int makePERAfterReservationRequest(char *request, const simcoPacket_t *sp);
extern int makePBRAfterReservationRequest(char *request, const simcoPacket_t *sp);
extern int makePolicyRuleLifetimeChangeRequest(char *request, const simcoPacket_t *sp);
extern int makePolicyRuleStatusRequest(char *request, const simcoPacket_t *sp);
extern int makePolicyRuleListRequest(char *request);

#endif /* _SIMCO_CORE_H_ */
