/* protocol.h header files for protocol specifics */
/******************************************************************************
  This code is derived from work originally done within IMM 3.0
  Written by Winston Dang <wkd@hawaii.edu>

  * Copyright (c) University of Hawaii 1993. All rights reserved.
  *  
  * License is granted to copy, to use, and to make and to use derivative
  * works for research, educational, government or evaluation purposes, provided
  * that the University of Hawaii is acknowledged in all documentation pertaining
  * to any such copy or derivative work. University of Hawaii grants no other 
  * licenses expressed or imrplied. The University of Hawaii trade name should 
  * not be used in any advertising without its written  permission.
  *  
  * UNIVERSITY OF HAWAII MAKES NO REPRESENTATIONS CONCERNING EITHER THE
  * MERCHANTABILITY OF THIS SOFTWARE OR THE SUITABILITY OF THIS SOFTWARE
  * FOR ANY PARTICULAR PURPOSE.  The software is provided "as is" without
  * express or implied warranty of any kind.
  *  
  * These notices must be retained in any copies of any part of this software.
  ******************************************************************************/
/******************************************************************************
 * This code release was developed and written by 
 * Joe Macker and Winston Dang,
 * 1996, 1997
 ******************************************************************************/
#include <stdio.h>
#include <signal.h>    
#include <sys/types.h>    
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>    
#include <string.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/uio.h>
#ifndef SOLARIS
#include <unistd.h>
#else
#define u_int16_t unsigned short
#define u_int32_t unsigned long
#endif

#define VERSION 36
#define DEFAULT_TTL 64
#define MAXUSERNAME 256 	/* The maximum length for the user ID string */
#define MINFILESIZE 0		/* Minimum file size server will send */
#define MAXFILES    8		/* Maximum number of files tracked by server */

#define MAXPACKETSHIFT 32	/* used in Recovery sect -defines bits in long*/
#define MAXPACKETS  8		/* used in Recovery sect -defines array size */

#define PACKETSIZE 1400		/* default packet size to multicast */
#define AUTOREQ	     3		/* automatic selective request flag */
#define MINWAIT	     2		/* recovery time period duration */
#define MAXWAIT	     30		/* maximum recovery cycle time period in sec */	
#define MAXFILESIZE 0xFFFFFFFF	/* largest file size */

#define BOOLEAN     unsigned char
#ifndef TRUE
#define TRUE                    1
#endif /* TRUE */
#ifndef FALSE                   
#define FALSE                   0
#endif /* FALSE */

#define T_MAX 1456		/* maximum packet size */
/****************************************************************************/
/* The following section details the layout of the packet sent by both
   the client and the server 
 */  
/* basic header packet format - used in packet formats below */
struct bufheader {
    u_char	version;	     /* Version ID coming from server */
    u_char	unused1;	     /* not used */	
    u_int16_t	fid;		     /* file ID coming from server */
    u_char	type;		/* See BUF_TYPE defs below */
    u_char	flags;		/* See BUF_FLG  defs below */
};
/****************************************************************************/
/* PACKET TYPES SENT BY SERVERS */
/****************************************************************************/
/* server data packet format -regular id and data packets 
	ID packets contain the following ASCII string info in the data area
		filename, sender name, hold time
	Data packets contained the packetized data in the file
*/
/* Identification packet */
#define BUFID_SIZE (sizeof(struct bufheader) + 6)
struct bufid {
    struct bufheader	head;	/* defined above */
    u_int16_t	hold_duration;	/* duration of hold */
    u_int32_t	file_size;	/* byte offset position in file */
    u_char 	data[T_MAX]; /* payload data */
};

/* Data packet */
#define BUFDEF_SIZE (sizeof(struct bufheader) + 6)
struct bufdef {
    struct bufheader	head;	/* defined above */
    u_int16_t 	unused2;       /* not used */
    u_int32_t	bytepos;	/* byte offset position in file */
    u_char 	data[T_MAX];	/* payload data */
};

/* command packet */
#define BUFCMD_SIZE (sizeof(struct bufheader) + 6)
struct bufcmd {
    struct bufheader	head;	/* defined above */
    u_int16_t	unused2;       	/* not used */
    u_int32_t	cycle_duration;	/* byte offset position in file */
    u_char 	data[T_MAX]; /* payload data */
};

/****************************************************************************/
/* PACKET TYPES SENT BY CLIENTS */
/****************************************************************************/
/* client missing packet request packet format */
#define BUFMISSDEF_SIZE (sizeof(struct bufheader) + 10)
struct bufmissdef {
    struct bufheader	head;    	/* defined above */
    u_int16_t	unused2;    	/* not used */
    u_int32_t	num_requests;	/* byte offset position in file */    
    u_char	server[4];	/* IP of server */
    u_int32_t	data[ T_MAX / sizeof(u_int32_t)];  /* list of missing packets requested */
};
/*	    for (counter = 0; counter <= max; counter++) { */

/* client statistical info packet - reports reception of packets from server */
#define BUFSTATDEF_SIZE (sizeof(struct bufheader) + 12)
struct bufstatdef {
    struct bufheader	head;	/* defined above */    
    u_int16_t	packet_recv;
    u_char	server[4];
    u_int16_t	good;
    u_int16_t	bad;
    u_int16_t	retries;
    u_char data[T_MAX];
};

/* client new member packet format */
struct bufmemberdef {
    struct bufheader	head;    	/* defined above */
    u_int16_t 	myversion;    	/* not used */
};

/****************************************************************************/
/* statistical information - used only internally by client */
struct stattype {
    struct sockaddr_in addr_serv;
    int len_addr_serv;
    char name_user[MAXUSERNAME];
    char portgrp[10];
    char server[4];
    unsigned short badtrans;
    unsigned short goodtrans;
    unsigned short retries;
    unsigned short pack_recv;
    unsigned short last_buf_flag;
    int	file_received_flag;
    int heard_nack_flag;
    int alarmoff;
    int alarmwentoff;
    struct nodetype *lastreceived;
};

/****************************************************************************/
struct window_packets {
	unsigned int BasePosition;
	u_long counter;
	u_long RecPegPosition[MAXPACKETS];
	u_long MissPegPosition[MAXPACKETS];
	struct window_packets *prev;
	struct window_packets *next;
};

struct bufinfo {
    int updateflag;		/* file has been updated indicator */
    int maxsize;		/* maximum size packet received */
    struct window_packets *head;  /* head of link list of pegboards */
    struct window_packets *tail;  /* tail of link list of pegboards */
 };

struct nodetype {
    int fid;			/* file ID coming from server */    
    int	 ofp;			/* file ID used for temporary file */
    int flag;			/* Flags from server */
    char tmpfile[MAXUSERNAME];		/* temporary file name used */
    char currfile[MAXUSERNAME];		/* file name */
    char sendername[50];	/* name of sender */    
    unsigned char ipaddr[4];	/* servers ipaddress */
    unsigned long  age;		/* age of file */    
    unsigned long min;		/* lowest not received packet number */
    unsigned long max;		/* highest packet number received */
    unsigned long bytes_written; /* total number of bytes written */
    unsigned long count;	/* file position */
    unsigned long total;	/* file size */
    int serverflags;		/* Flags from server */
    int serverPackAck;		/* server heard my Pack */
    int toggleflag;		/* flag to determine state change */ 
    int transmitcode;		/* status of transmission */
    int hold;			/* duration of hold */
    int recovery_cycle_time;	/* duration of recovery cycle */
    struct bufinfo buf;
};

/*************************************************************************/
/* data struct for ticket system used below */
struct hosttype {
    int   id;			/* assigned client id for local host */
    unsigned char address[4];	/* ip address of server */
    unsigned int fid;	/* file id from server */
    struct nodetype node;	        /* pointer to where data is kept */
    struct hosttype *prev;		/* link list pointer */
    struct hosttype *next;		/* link list pointer */
};

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


#define BUF_TYPE_ID	0	/* file identification packet */
#define BUF_TYPE_DATA 	1	/* data packet */
#define BUF_TYPE_CMD	2	/* command packet */
#define BUF_TYPE_NEW_MEM  5	/* new member command */
#define BUF_TYPE_MISS_REQ 6	/* missing packet request */
#define BUF_TYPE_MISS_ANS 7	/* missing packet ack */
#define BUF_TYPE_REQUEST  8	/* request to server for file */
#define BUF_TYPE_BOMB	  9	/* single server - request to stop sent */
#define BUF_TYPE_STAT	  10	/* statistics response to request */
#define BUF_TYPE_IGNORE	  255	/* ignore this packet - throw away */

#define BUF_FLG_EOF	1	/* END OF FILE FLAG */
#define BUF_FLG_PACK 	2	/* request client ack */
#define BUF_FLG_NACK	4	/* request client send nack */
#define BUF_FLG_REPEAT  8	/* repeat packet */
#define BUF_FLG_ARCHIVE 16	/* archive file only */
#define BUF_FLG_EXECUT	32	/* executable file */
#define BUF_FLG_TOGGLE	64	/* toggles every state change */
#define BUF_FLG_AUTOREQ 128	/* automatic request for packets on */

/* packet transmission codes */
#define TRANSMISSION_START 0
#define TRANSMISSION_OK    1
#define TRANSMISSION_BAD   2
#define TRANSMISSION_RECOV 3
#define TRANSMISSION_REST  4
 
/* buffer recovery codes */
#define RECOV_PUT     0
#define RECOV_GET     1
#define RECOV_INIT    2
#define RECOV_FREE    3
#define RECOV_TEST    4
#define RECOV_MISS    5
#define RECOV_MISS_FREE 6

#ifdef MAIN
int sock,xmitsock;
int debug = 0;
int fullscrflag = -1;
int xvflag = 0;
char group[17]="";            /* multicast ip address */
u_char myipaddress[4];
unsigned char ttl= DEFAULT_TTL;
FILE *logfp;
#else
extern unsigned char ttl;
extern FILE *logfp;
extern char myipaddress[];
#endif


