/*
 * Copyright (c) 2000 Columbia University
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that: (1) source code distributions
 * retain the above copyright notice and this paragraph in its entirety, (2)
 * distributions including binary code include the above copyright notice and
 * this paragraph in its entirety in the documentation or other materials
 * provided with the distribution, and (3) all advertising materials mentioning
 * features or use of this software display the following acknowledgement:
 * ``This product includes software developed by Columbia University
 * and its contributors.'' Neither the name of the University nor the names 
 * of its contributors may be used to endorse or promote products derived 
 * from this software without specific prior written permission.
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Written by Ping Pan, Columbia University, 2000
 *
 * The author would like to thank Bell Labs for providing time and freedom
 * to complete this work. Please forward bug fixes, enhancements and questions
 * to pingpan@cs.columbia.edu.
 */

#ifndef _YESTAT_H_
#define _YESTAT_H_

/* The unique UDP port number for yestat()
 *
 * Actually, when taking shower this morning, just thought: "yestat() can 
 * get/add/delete data to/from a running process at a lala's land. 
 * So does COPS." When time is available, I should use the COPS TCP port 
 * plus MD5 instead. 
 * .... Writing yet another internet draft on policy is a drag though.
 * Besides, I never had any luck on policy: IBM killed my COPS project
 * because they wanted to kiss LDAP's rear. Bell Labs had killed it along
 * with a hyped and cheating router project, while not knowing its usage 
 * and existance. Damnit, policy no more!
 * 
 * - Ping Pan, 4/1/2000
 */

#define YESSIR_STAT_PORT	1638	/* 0x666 */


/* Maximum buffer size
 */

#define YESTAT_MAXBUF		9160


/*
 * yestat message structure
 */

struct yestat_msg {
	u_char	type;		/* type of message, see below */
	u_char	ack;		/* ack/nack (see below) */
	u_char	more;		/* message fragment information (see below)  */
	u_char	rsvd;		/* reserved */
	u_long	len;		/* length of this entire message in bytes */
	u_long	id;		/* sender's id, (not implemented yet) */
};


/* yestat types
 */

#define		YESTAT_GET_VER		1	/* get version */
#define 	YESTAT_GET_SUM		2	/* get summary */
#define		YESTAT_GET_IF		3	/* get interface info */
#define		YESTAT_GET_FLOWDUMP	4	/* get flow info */
#define		YESTAT_GET_COUNTER	5	/* get counters */
#define		YESTAT_GET_PENDING	6	/* get pending flows */

#define		YESTAT_DEL_FLOW		20	/* delete a flow */
#define		YESTAT_DEL_RESV		21	/* delete the resv of a flow */


/* ack/nack flag:  if a router does not support the requested message type,
 * or cannot process the message due to lack of resource, etc. it sends
 * back the original request with YESTAT_NACK.
 */

#define YESTAT_ACK	1
#define YESTAT_NACK	2


/* more flag: if a reply is too large (for example, large than a socket's 
 * sending buffer), the router needs to send the reply in multiple portions.
 * Note: copied idea from SMDS L2_PDU.
 */

#define YESTAT_SINGLE	1		/* this is the only fragment */ 
#define YESTAT_MORE	2		/* more to come */
#define YESTAT_LAST	3		/* this is the last */


struct yestat_version_string {
	struct yestat_msg	req;
	u_char			string_len;	/* length of version string */
	u_char			ver_string[3];
	/*
	 * more ascii follows from here.
	u_char			more_ver_string[];
	*/
};


struct yestat_summary {
	struct yestat_msg	req;
	u_long			max_flow;	/* max supprted flow */
	u_long			curr_flow;	/* current flows */
	u_long			curr_pend_flow;	/* the pending flows */
	u_long			total_if;	/* total num of interfaces */
};


struct yestat_if_info {
	u_int32_t		index;
	u_char			name[IFNAMSIZ];

#define YESTAT_RESV_ENABLE	1		/* can make reservation */
#define YESTAT_RESV_DISABLE	2		/* no reservation allowed */
#define YESTAT_SICK_RIF		3		/* something's wrong with it */
	u_int8_t		state;

	u_int8_t		type;
	u_int16_t		l2_hdrlen;
	u_int32_t		link_bw;
	u_int32_t		max_resv_bw;
	u_int32_t		avail_bw;

	u_int32_t		int_addr;	/* interface address */
	u_int32_t		int_mask;
	u_int32_t		int_dstaddr;

	u_int32_t		rx_pkt;
	u_int32_t		rx_byte;
	u_int32_t		rx_err;
	u_int32_t		tx_pkt;
	u_int32_t		tx_byte;
	u_int32_t		tx_err;

};

struct yestat_if {
	struct yestat_msg	req;

	/* interface info begins here 
	 *
	 struct yestat_if_info	if_info[0]; 
	 */
};


struct yestat_out_info {
	u_int16_t	out_if;		/* output if-index */

#define YESTAT_RESV	1
#define YESTAT_PENDING	2
	u_int16_t	state;		/* reserved or not */

	u_int32_t	rhandle;	/* reservation handle */
	u_int16_t	eff_ftype;	/* effective flowspec type */
	u_int16_t	req_ftype;	/* requested flowspec type */
	u_int32_t	eff_rate;	/* effective reserved rate */
	u_int32_t	req_rate;	/* requested reserved rate */
	u_int16_t	is_service;	/* IntServ service type */
	u_int16_t	ds_phb;		/* DiffServ PHB */
};


struct yestat_flow_info {
	u_int32_t	da;		/* dst addr */
	u_int32_t	sa;		/* src addr */
	u_int16_t	dp;		/* dst port */
	u_int16_t	sp;		/* src port */
	u_int32_t	fid;		/* flow id */
	u_int32_t	fhandle;	/* handle to TC */
	u_int32_t	max_lifetime;	/* max. lifetime */
	u_int32_t	curr_lifetime;	/* current lifetime */
	u_int16_t	in_if;		/* ingress index */
	u_int16_t	num_out_if;	/* numnber of egress if's */

	/* 
	 * followed by the egress info: 
	 * struct yestat_out_info	out_info[0];
	 */

};


struct yestat_flow {
	struct yestat_msg	req;

	/* 
	 * more entries follow from here 
	 *
	 * struct yestat_flow_info	flow_info[0];
	 */

};


struct yestat_cnt {
	u_int32_t	rtcp_rx_pkt;
	u_int32_t	rtcp_tx_pkt;
	u_int32_t	rx_host;
	u_int32_t	rx_mcast;

	/* protocol level errors */
	u_int32_t	rx_bad_pkt;
	u_int32_t	incomp_pkt;
	u_int32_t	bad_rtcp;
	u_int32_t	rtcp_bad_version;
	u_int32_t	rtcp_bad_len;
	u_int32_t	rtcp_dup_pt;
	u_int32_t	rtcp_unknown_pt;
	u_int32_t	yessir_unknown_obj;
	u_int32_t	rx_rejected_yessir;
	u_int32_t	null_yessir;
	u_int32_t	missing_yessir_obj;
	u_int32_t	unknown_action;
	u_int32_t	unknown_ftype;
	u_int32_t	dst_unreach;
	u_int32_t	looping;
	u_int32_t	no_memory;
	u_int32_t	resv_attempt;
	u_int32_t	resv_success;

	/* table management */
	u_int32_t	refill_flow_tab;
	u_int32_t	refill_flow_failed;
	u_int32_t	refill_oentry_tab;
	u_int32_t	refill_oentry_failed;
	u_int32_t	refill_time_tab;
	u_int32_t	refill_time_failed;
	u_int32_t	refill_pending_tab;
	u_int32_t	refill_pending_failed;
	u_int32_t	deplete_flow_tab;
	u_int32_t	deplete_oentry_tab;
	u_int32_t	deplete_tentry_tab;
	u_int32_t	deplete_pentry_tab;
	u_int32_t	add_flow_failed;
	u_int32_t	add_tentry_failed;
	u_int32_t	del_nonexist_flow;
	u_int32_t	no_pending_bucket;
	u_int32_t	no_pending_entry;
	u_int32_t	timer_outsync;
};


#endif
