/*
 * 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/Bell Labs, 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 RTP_YESSIR_H
#define RTP_YESSIR_H

/* YESSIR: resource reservation extension 
 */

/* RTCP extension:
 * the resource reservation payload type 
 */
#define RTCP_PT_SIR	205	/* sender initiated  reservation */
#define RTCP_PT_RIR	206	/* reservation information report */

/*
 * Overall structure:
 *
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |V=2|P|    RC   |    PT         |             length            | header
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                         SSRC of sender                        |
 * +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ 
 * |                                                               |
 * //                   YESSIR objects                            //
 * //                       ...                                   //
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 *  The objects can be at any order.
 */

/* see rtp.h
struct rtcphdr {
	u_int16_t rh_flags;
	u_int16_t rh_len;
	u_int32_t rh_ssrc;
};
 */


/* YESSIR Object header:
 *                  
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |          Length               |   Obj-Type    |   ...         |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 *   Length:
 *           The total length of the object in bytes.
 *   Obj-Type: (8 bits)
 *        1  =  COMMAND
 *        2  =  FLOWSPEC
 *        3  =  MONITOR
 *        4  =  ERROR
 *           
 */

struct yessir_obj_hdr {
	u_int16_t	len;
	u_int8_t	obj_type;
	u_int8_t	rsv;
};

#define YESSIR_CMD		1	/* Command Object */
#define YESSIR_FSPEC		2	/* Flowspec Object */
#define YESSIR_MON		3	/* Monitor Object */
#define YESSIR_ERR		4	/* Error Object */

#define YESSIR_OBJ_LEN(x)	(ntohs((x)->len))
#define YESSIR_OBJ_TYPE(x)	((x)->obj_type)


/* COMMAND Object:
 *  This object must present from the RTCP messages originated from
 *  the senders. All relavent routers along the way must parse 
 *  the object to make the proper reservation.
 *
 * Format:
 *                  
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |          Length (8)           |  Obj-Type (1) |S|V|B| rsv (0) |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |  Action       |    rsv (0)    |       Refresh Interval        | 
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 *   Obj-Type:
 *             1           COMMAND
 *   Length:
 *             8           the number of bytes in total
 *   Style Flag (S):
 *             0           distinct reservation style
 *             1           shared reservation style
 *   Verification Flag (V):
 *             0           reservation is successful all the way
 *             1           reservation failed on some links
 *   Bad Reservation Flag (B):
 *             1           critial error(s) occured upstream;
 *                         ignore the reservation downstream.
 *             0           otherwise,
 *   Action:
 *             1           make reservation
 *             2           teardown existing reservation
 *   Refresh Interval:
 *         The refresh period used to generate this reservation 
 *         message in seconds. The default initial value is 
 *         30 seconds.
 *
 */

struct yessir_cmd {
	u_int16_t	len;
	u_int8_t	obj_type;
	u_int8_t	flag;
	u_int8_t	action;
	u_int8_t	padding;
	u_int16_t	refresh;
};

#define YESSIR_STYLE_MASK	0x80
#define YESSIR_STYLE_OFFSET	7
#define YESSIR_DISTINCT_STYLE	0x00
#define YESSIR_SHARED_STYLE	0x01
#define YESSIR_STYLE_OF(x)						\
	(((x)->flag & YESSIR_STYLE_MASK) >> YESSIR_STYLE_OFFSET)

#define YESSIR_VERF_MASK	0x40
#define YESSIR_VERF_OFFSET	6
#define YESSIR_VERF_OF(x)						\
	(((x)->flag & YESSIR_VERF_MASK) >> YESSIR_VERF_OFFSET)
#define YESSIR_BROKEN_PIPE	(1 << YESSIR_VERF_OFFSET)
#define YESSIR_SET_VERF(x)	((x)->flag |= YESSIR_BROKEN_PIPE)

#define YESSIR_BAD_MASK		0x20
#define YESSIR_BAD_OFFSET	5
#define YESSIR_BAD(x)						\
	(((x)->flag & YESSIR_BAD_MASK) >> YESSIR_BAD_OFFSET)
#define YESSIR_RESV_BAD		(1 << YESSIR_BAD_OFFSET)
#define YESSIR_SET_BAD(x)	((x)->flag |= YESSIR_RESV_BAD)

#define YESSIR_RESV		0x01
#define YESSIR_RESVTEAR		0x02
#define YESSIR_INVALID_ACT(x)				\
	((x->action != YESSIR_RESV) && 			\
	 (x->action != YESSIR_RESVTEAR)) ? 1 : 0

#define YESSIR_DEF_REFRESH	15	/* in seconds */


/*
 * FLOWSPEC Object:
 *
 * This Object must present along with the COMMAND object.
 *
 * Format:
 *                  
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |          Length               |  Obj-Type (2) |    Type       |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * //                   Flowspec Info                             //
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 *   Obj-Type:
 *             2           FLOWSPEC
 *   Length:
 *                         the number of bytes in total
 *   Type:
 *             1         IntServ FLOWSPEC format (defined by RFC2210)
 *             2         DSCP (DiffServ Control Point)
 */

struct yessir_fspec {
	u_int16_t	len;
	u_int8_t	obj_type;
	u_int8_t	ftype;
/*
 *	follow by the actual flowspec
 */
};


#define YESSIR_MB_FSPEC		0xFF	/* meausrement-based */

#define YESSIR_IS_FSPEC		0x01
#define YESSIR_DS_FSPEC		0x02
#define YESSIR_VALID_FSPEC	(YESSIR_IS_FSPEC | YESSIR_DS_FSPEC)


/*
 * Network Monitoring Object:
 *
 * This object is optional to be sent by the senders.
 *
 * Format:
 *                  
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |          Length               |  Obj-Type  (3) |   Type       |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * //                   Monitoring Info                           //
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 *   Obj-num:
 *             3           MONITOR
 *   Length:
 *                         the number of bytes in total
 *   Type:
 *             1         Adspec Format (RFC2210)
 *             2         Simple monitoring format
 */

#define YESSIR_MON_ADSPEC	1

struct yessir_mon {
	u_int16_t	len;
	u_int8_t	obj_type;
	u_int8_t	type;
};

/* Simple network monitoring format:
 *
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |          Length               |  Obj-Type  (3) |   Type       |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |         Hop Count             |          rsvd (0)             |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
 * |                 Minimum Path Bandwidth                        |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
 *
 */

struct yessir_simp_mon {
	struct yessir_mon	hdr;
	u_int16_t		hop_cnt;
	u_int16_t		rsvd;
	u_int32_t		min_bw;
};


/*
 * Reservation Error Object:
 *
 * The object should be a part of the RTCP SIR message.
 *
 * Format:
 *                  
 *  0                   1                   2                   3
 *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |          Length               |  Obj-Num  (2) |    Rsv        |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |               IPv4 Error Node Address (4 bytes)               |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                            Error Code                         |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |           Error Code          |          Error Value          |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 *
 *   Obj-num:
 *             4           ERROR
 *   Length:
 *             12          the number of bytes in total
 *   Node Address:
 *                         the node where a critical error has taken place
 *   Error Code:
 *                         error reason
 *   Error Value:
 *                         additional information
 *   
 */

struct yessir_IPv4_err {
	u_int16_t	len;
	u_int8_t	obj_num;
	u_int8_t	rsv;
	u_int32_t	err_addr;
	u_int16_t	err_code;
	u_int16_t	err_val;
};

#define YE_MISSRTCP		1	/* missing rtcp payloads */
#define YE_OBJCONFLICT		2	/* conflicting objects */
#define YE_BADOBJLEN		3	/* bad object length */
#define YE_UNKNOWNOBJ		4	/* unknown object */
#define YE_MISSOBJ		5	/* missing yessir objects */
#define YE_UNKNOWNACT		6	/* unknown action in COMMAND */
#define YE_BADFLOWSPEC		7	/* unknown ftype in FLOWSPEC */
#define YE_BADINTSERV		8	/* bad intserv flowpsec */
#define YE_NOBUF		9	/* no resource */
#define YE_CANNOTRESV		10	/* cannot make reservation */
#define YE_REJECT		11	/* failed admission ctl */
#define YE_NORESOURCE		12	/* no resource at this time */

#endif
