/*
	This file contains default policy-statements.

	NOTE: VIM users can activate syntax highlighting with ':syntax on'.
*/

#include "@resolved_sysconfdir@/format-statements.conf"
#include "@resolved_sysconfdir@/map-statements.conf"

policy-options {
	/*
		A policy that filters everything.
	*/
	policy-statement IGNORE_ALL {
		term REJECT {
			then reject;
		}
		apply-format PREFIX_FILTER_FORMAT;
	}

	/*
		A policy that filters RFC 1918 (private) IP space.
	*/
	policy-statement IGNORE_RFC_1918 {
		term REJECT_RFC_1918 {
			from prefix [ 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 ];
			then reject;
		}
		apply-format PREFIX_FILTER_FORMAT;
	}

	/*
		A policy that filters loopback (127.0.0.0/8) IP space.
	*/
	policy-statement IGNORE_LOOPBACK {
		term REJECT_LOOPBACK {
			from prefix 127.0.0.0/8;
			then reject;
		}
		apply-format PREFIX_FILTER_FORMAT;
	}
	
	/*
		A policy that filters interfaces which ARE NOT connected to other known
		interfaces.
	*/
	policy-statement IGNORE_EDGE_INTERFACE {
		term REJECT_EDGE {
			from connected false;
			then reject;
		}
		apply-format ICMP_FORMAT;
	}

	/*
		A policy that filters interfaces which ARE connected to other known
		interfaces.
	*/
	policy-statement IGNORE_BACKBONE_INTERFACE {
		term REJECT_EDGE {
			from connected true;
			then reject;
		}
		apply-format ICMP_FORMAT;
	}

	/*
		A policy that sets the tos/dscp/precedence bits on a per prefix bases.

		NOTE: A default setting can be configured within some modules. Only the
		ICMP monitoring module supports this currently.
	*/
	policy-statement SET_TOS_BITS {
		term LOOPBACK {
			from prefix [ 10.0.0.0/24 ];
			then {
				set dscp 63; /* Network control */
			}
		}
		term VOIP_HOST {
			from prefix [ 10.0.250.0/24 ];
			then {
				set precedence 5; /* Expedited Forwarding */
			}
		}
		apply-format PREFIX_FILTER_FORMAT;
	}

	/*
		An ICMP packet loss policy.
	*/
	policy-statement PACKET_LOSS {
		/* Set proper channel for edge or backbone interface. */
		term DEFAULT_CHANNEL {
			then set interface-channel	interface-edge;
		}
		term BACKBONE_CHANNEL {
			from connected	true;
			then set interface-channel	interface-backbone;
		}

		/*
			Set a packet loss alarm if packet loss has reached at least 90% over
			the last 60 seconds.
		*/
		term HEAVY_PACKET_LOSS_TIMEOUT {
			from {
				protocol		icmp;
				event			packet-loss;
				type			timeout;
				at-least		90;
				interval		60;
				state			[ normal warning recovery ];
			}
			then {
				/* Collect known information about the IP that triggered this event from the database. */
				apply-map 	IP_TO_DATA_MAP;

				/* Change the state of this IP to failure. */
				set {
					state			failure;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"Interface Down (@ip@ timeout)";
						detail	"@loss@% packet loss to @snmp:ifDescr@ (@ip@) over the last @interval@ secs.";
						channel	@interface-channel@;
					}

					/* Log this event. */
					syslog {
						detail	"DOWN: @snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] - @loss@% loss over @interval@ sec.";
						channel	@interface-channel@;
					}

					/* Send an email notification about this event. */
					email {
						brief		"DOWN";
						detail	"@snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] @loss@% loss";
						channel	@interface-channel@;
					}
				}
				accept;
			}
		}
		term HEAVY_PACKET_LOSS_NON_TIMEOUT {
			from {
				protocol		icmp;
				event			packet-loss;
				at-least		90;
				interval		60;
				state			[ normal warning recovery ];
			}
			then {
				/* Collect known information about the IP that triggered this event from the database. */
				apply-map 	IP_TO_DATA_MAP;

				/* Change the state of this IP to failure. */
				set {
					state			failure;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"Interface Down (@ip@ @code@)";
						detail	"@loss@% packet loss to @snmp:ifDescr@ (@ip@) over the last @interval@ secs. Recieved type @type@ and code @code@.";
						channel	@interface-channel@;
					}

					/* Log this event. */
					syslog {
						detail	"DOWN: @snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] - @loss@% loss over @interval@ sec. Type @type@, code @code@";
						channel	@interface-channel@;
					}

					/* Send an email notification about this event. */
					email {
						brief		"DOWN";
						detail	"@snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] @loss@% loss, type @type@, code @code@";
						channel	@interface-channel@;
					}
				}
				accept;
			}
		}

		/*
			Clear a packet loss alarm if packet loss has dropped to at least 1%
			over the last 60 seconds.
		*/
		term HEAVY_PACKET_LOSS_RECOVERY {
			from {
				protocol		icmp;
				event			packet-loss;
				at-most		1;
				interval		60;
				state			failure;
			}
			then {
				/* Collect known information about the IP that triggered this event from the database. */
				apply-map 	IP_TO_DATA_MAP;

				/* Change the state of this IP to recovery and clear the historical data for this IP. */
				set {
					state			recovery;
					statistics	clear-history;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"Interface Up (@ip@ reachable)";
						detail	"@loss@% packet loss to @snmp:ifDescr@ (@ip@) over the last @interval@ secs. Average latency is @rtt@ ms.";
						channel	@interface-channel@;
					}

					/* Log this event. */
					syslog {
						detail	"UP: @snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] - @loss@% loss over @interval@ sec.";
						channel	@interface-channel@;
					}

					/* Send an email notification about this event. */
					email {
						brief		"UP";
						detail	"@snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] @loss@% loss, @rtt@ ms";
						channel	@interface-channel@;
					}
				}
				accept;
			}
		}

		/*
			Set a packet loss warning if packet loss has reached at least 30% over
			the last 5 minutes.
		*/
		term LIGHT_PACKET_LOSS {
			from {
				protocol		icmp;
				event			packet-loss;
				at-least		30;
				interval		300;
				state			[ normal recovery ];
			}
			then {
				/* Collect known information about the IP that triggered this event from the database. */
				apply-map 	IP_TO_DATA_MAP;

				/* Change the state of this IP to warning. */
				set {
					state		warning;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"Packet Loss (@ip@ at @loss@% loss)";
						detail	"@loss@% packet loss to @snmp:ifDescr@ (@ip@) over the last @interval@ secs. Average latency is @rtt@ ms.";
						channel	@interface-channel@;
					}

					/* Log this event. */
					syslog {
						detail	"PACKET LOSS WARNING: @snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] - @loss@% loss over @interval@ sec.";
						channel	@interface-channel@;
					}

					/* Send an email notification about this event. */
					email {
						brief		"LOSS WARNING";
						detail	"@snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] @loss@% loss, @rtt@ ms";
						channel	@interface-channel@;
					}
				}
				accept;
			}
		}

		/*
			Clear a packet loss warning if packet loss has dropped to at most 1%
			over the last 5 minutes.
		*/
		term LIGHT_PACKET_LOSS_RECOVERY {
			from {
				protocol		icmp;
				event			packet-loss;
				at-most		1;
				interval		300;
				state			warning;
			}
			then {
				/* Collect known information about the IP that triggered this event from the database. */
				apply-map 	IP_TO_DATA_MAP;

				/* Change the state of this IP to recovery. */
				set {
					state		recovery;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"Packet Loss Subsided (@ip@ at @loss@% loss)";
						detail	"@loss@% packet loss to @snmp:ifDescr@ (@ip@) over the last @interval@ secs. Average latency is @rtt@ ms.";
						channel	@interface-channel@;
					}

					/* Log this event. */
					syslog {
						detail	"PACKET LOSS RECOVERY: @snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] - @loss@% loss over @interval@ sec.";
						channel	@interface-channel@;
					}

					/* Send an email notification about this event. */
					email {
						brief		"LOSS RECOVERY";
						detail	"@snmp:sysName.0@ @snmp:ifDescr@ @ip@ [@snmp:ifAlias@] @loss@% loss, @rtt@ ms";
						channel	@interface-channel@;
					}
				}
				accept;
			}
		}

		/* 
			This is an ICMP monitoring policy-statment, therefore it should adhere
			to the rules defined by 'format-statement ICMP_FORMAT'.
		*/
		apply-format ICMP_FORMAT;
	}

	/*
		A policy which demonstrates the 'tos-change' ICMP monitoring event.
	*/
	policy-statement TOS_CHANGE {
		/* Set proper channel for edge or backbone interface. */
		term DEFAULT_CHANNEL {
			then set interface-channel	interface-edge;
		}
		term BACKBONE_CHANNEL {
			from connected	true;
			then set interface-channel	interface-backbone;
		}
		term TOS_CHANGE {
			from {
				protocol		icmp;
				event			tos-change;
				not-equal	@tos@; /* Compares the transmitted value to the recieved value. */
			}
			then {
				/* Collect known information about the IP that triggered this event from the database. */
				apply-map 	IP_TO_DATA_MAP;

				/* Change the state of this IP to failure. */
				set {
					state			information;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"The TOS value changed from @tos@ to @tos-rx@";
						detail	"The packets TOS bits changed from @tos@ to @tos-rx@. This indicates that a device along the path to @ip@ is rewriting the TOS bits.";
						channel	@interface-channel@;
					}

					/* Send this event to the GUI for display. */
					syslog {
						detail	"@snmp:sysName.0@: The packets TOS bits changed from @tos@ to @tos-rx@. This indicates that a device along the path to @ip@ is rewriting the TOS bits.";
						channel	@interface-channel@;
					}
				}
				accept;
			}
		}
		apply-format ICMP_FORMAT;
	}

	/*
		A policy that verifies the source and community of an snmptrap is
		authorized to be recieved by the system.
	*/
	policy-statement AUTHORIZE_TRAP {
		/*
			Check the source and community of the snmptrap.
		*/
		term AUTHORIZE {
			from {
				source		[ 10.0.0.0/8 192.168.0.0/16 ];
				community	[ public ];
			}
			then next-policy;
		}
		term REJECT {
			then {
				output {
					/* Log this event. */
					syslog {
						detail	"@snmp:sysName.0@: Recieved an unauthorized SNMP Trap from @source@ using community '@community@'.";
						channel	security;
					}
				}

				/* Reject this snmptrap and stop processing it. */
				reject;
			}
		}

		/* 
			This is an snmptrap monitoring policy-statment, therefore it should
			adhere to the rules defined by 'format-statement SNMPTRAP_FORMAT'.
		*/
		apply-format SNMPTRAP_FORMAT;
	}

	/*
		Rejects authentification failure snmptraps.
	*/
	policy-statement IGNORE_AUTH_FAILURE_TRAP {
		term AUTHENTICATION_FAILURE {
			from {
				protocol		snmptrap;
				trap-type	authentication-failure;
			}
			then reject;
		}
		apply-format SNMPTRAP_FORMAT;
	}

	/*
		A sample policy that evaluates snmptraps.
	*/
	policy-statement LINK_TRAP {
		/* Set proper channel for edge or backbone interface. */
		term DEFAULT_CHANNEL {
			then set interface-channel	interface-edge;
		}
		term BACKBONE_CHANNEL {
			from connected	true;
			then set interface-channel	interface-backbone;
		}
		term LINK_DOWN {
			from {
				protocol		snmptrap;	/* This is an snmptrap. */
				trap-type	link-down;
			}
			then {
				apply-map SOURCE_IFNAME_TO_DATA_MAP;

				/* Change the state of this interface to failure. */
				set {
					state		failure;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"Interface Down (@snmp:ifName@ changed state to down)";
						detail	"Interface @snmp:ifName@ (@ip@) changed state to down.";
						channel	@interface-channel@;
					}

					/* Log this event. */
					syslog {
						detail	"LINK DOWN: @snmp:sysName.0@ @snmp:ifName@ @ip@ [@snmp:ifAlias@] - Interface changed state to down.";
						channel	@interface-channel@;
					}

					/* Send an email notification about this event. */
					email {
						brief		"DOWN";
						detail	"@snmp:sysName.0@ @snmp:ifName@ @ip@ [@snmp:ifAlias@] state changed to down";
						channel	@interface-channel@;	
					}
				}

				/* Accept this snmptrap and stop processing it. */
				accept;
			}
		}
		term LINK_UP {
			from {
				protocol			snmptrap;	/* This is an snmptrap. */
				trap-type		link-up;
			}
			then {
				apply-map SOURCE_IFNAME_TO_DATA_MAP;

				/* Change the state of this interface to recovery. */
				set {
					state		recovery;
				}
				output {
					/* Send this event to the GUI for display. */
					gui {
						brief		"Interface Up (@snmp:ifName@ changed state to up)";
						detail	"Interface @snmp:ifName@ (@ip@) changed state to up.";
						channel	@interface-channel@;
					}

					/* Log this event. */
					syslog {
						detail	"LINK UP: @snmp:sysName.0@ @snmp:ifName@ @ip@ [@snmp:ifAlias@] - Interface changed state to up.";
						channel	@interface-channel@;
					}

					/* Send an email notification about this event. */
					email {
						brief		"UP";
						detail	"@snmp:sysName.0@ @snmp:ifName@ @ip@ [@snmp:ifAlias@] state changed to up";
						channel	@interface-channel@;
					}
				}

				/* Accept this snmptrap and stop processing it. */
				accept;
			}
		}
		/* 
			This is an snmptrap monitoring policy-statment, therefore it should
			adhere to the rules defined by 'format-statement SNMPTRAP_FORMAT'.
		*/
		apply-format SNMPTRAP_FORMAT;
	}

	policy-statement RMON_TRAP {
		term RMON_RISING_ALARM {
			from {
				protocol snmptrap;
				event		snmp:risingAlarm;
			}
			then {
				apply-map SOURCE_TO_ELEMENT_DATA;
				set {
					state failure;
				}
				output {
					gui {
						brief		"RMON Rising: @snmp:eventDescription@ (owner: @snmp:alarmOwner@)";
						detail	"The RMON rising alarm '@snmp:eventDescription@' was recieved. This alarm is owned by '@snmp:alarmOwner@'.";
						channel	rmon;
					}
					syslog {
						detail	"@snmp:sysName.0@: rmon rising alarm @snmp:eventDescription@ - owner @snmp:alarmOwner@";
						channel	rmon;
					}
				}
				accept;
			}
		}
		term RMON_FALLING_ALARM {
			from {
				protocol snmptrap;
				event		snmp:fallingAlarm;
			}
			then {
				apply-map SOURCE_TO_ELEMENT_DATA;
				set {
					state recovery;
				}
				output {
					gui {
						brief		"RMON Falling: @snmp:eventDescription@ (owner: @snmp:alarmOwner@)";
						detail	"The RMON falling alarm '@snmp:eventDescription@' was recieved. This alarm is owned by '@snmp:alarmOwner@'.";
						channel	rmon;
					}
					syslog {
						detail	"@snmp:sysName.0@: rmon falling alarm @snmp:eventDescription@ - owner @snmp:alarmOwner@";
						channel	rmon;
					}
				}
				accept;
			}
		}
		/* 
			This is an snmptrap monitoring policy-statment, therefore it should
			adhere to the rules defined by 'format-statement SNMPTRAP_FORMAT'.
		*/
		apply-format SNMPTRAP_FORMAT;
	}

	policy-statement LOG_UNKNOWN_TRAP {
		term UNKNOWN_TRAP {
			then {
				apply-map	SOURCE_TO_ELEMENT_DATA;
				set {
					state		information;
				}
				output {
					syslog {
						detail	"@snmp:sysName.0@: UNKNOWN SNMPTRAP: event: @event@, type: @trap-type@, community: @community@";
						channel	default;
					}
				}
				accept;
			}
		}

		/* 
			This is an snmptrap monitoring policy-statment, therefore it should
			adhere to the rules defined by 'format-statement SNMPTRAP_FORMAT'.
		*/
		apply-format SNMPTRAP_FORMAT;
	}

	policy-statement IGNORE_GENERIC_SYSLOG {
		term REJECT_MESSAGE_REPEATS {
			from {
				protocol	syslog;
				msg	"^last message repeated";
			}
			then reject;
		}
		apply-format SYSLOG_FORMAT;
	}

	policy-statement LOG_UNKNOWN_SYSLOG {
		term LOG {
			then {
				apply-map 	SOURCE_TO_ELEMENT_DATA;
				set {
					state		information;
				}
				output {
					syslog {
						detail	"@snmp:sysName.0@: UNHANDLED SYSLOG: @content@";
						channel	software;
					}
				}
				accept;
			}
		}
		apply-format SYSLOG_FORMAT;
	}

	/*
		A policy that determines the state based on multiple monitoring inputs.
	*/
	policy-statement UPDATE_STATE {
		term UPDATE_ICMP {
			from {
				event				update;
				icmp-state		[ normal recovery warning ];
				snmptrap-state	failure;
			}
			then {
				set {
					icmp-state		failure;
					snmptrap-state	normal;
				}
				accept;
			}
		}
		apply-format STATE_FORMAT;
	}

	policy-statement EXPIRE_STATE {
		/*
			Expire events from state storage after a hour.
		*/
		term EXPIRE_STATE {
			from {
				event				expire;
				age				3600;
			}
			then {
				set {
					state			clear;
				}
				accept;
			}
		}

		apply-format STATE_FORMAT;
	}

	/*
		This policy-statement takes all new GUI events and either adds them to
		the lists of events or replaces existing events with the new event.
	*/
	policy-statement UPDATE_GUI_EVENT {
		term REWRITE_UNKNOWN {
			from {
				event		update;
				element-id	0;
			}
			then {
				set {
					element-id 2; /* id of undiscovered host */
				}
			}
		}
		/* ICMP ip recovery clears SNMPTrap interface failure. */
		term ICMP_CLEARS_SNMPTRAP {
			from {
				event		update;
				protocol	icmp;
				state		recovery;
			}
			then {
				set {
					match-label-list			"snmptrap";

					snmptrap-match-field		"element, interface, channel";
					snmptrap-match-state		"warning, failure";
					snmptrap-match-action	"clear";
				}
				accept;
			}
		}
		/* Information alarm clears duplicate information alarm. */
		term INFORMATION {
			from {
				event		update;
				state		information;
			}
			then {
				set {
					match-label-list		"strict";

					strict-match-field	"element, interface, ip, protocol, channel, brief, detail";
					strict-match-state	"information";
					strict-match-action	"clear";
				}
				accept;
			}
		}
		/* Recovery alarm clears dupliate recovery and failure/warning alarms that
			match element, interface, ip and channel.
		*/
		term RECOVERY {
			from {
				event		update;
				state		recovery;
			}
			then {
				set {
					match-label-list		"loose, strict";

					loose-match-field		"element, interface, ip, channel";
					loose-match-state		"failure, warning";
					loose-match-action	"clear";

					strict-match-field	"element, interface, ip, protocol, channel";
					strict-match-state	"recovery";
					strict-match-action	"clear";
				}
				accept;
			}
		}
		/* Failure/warning alarm clears duplicate failure/warning and recovery alarms that
			match element, interface, ip and channel.
		*/
		term FAILURE {
			from {
				event		update;
				state		[ failure warning ];
			}
			then {
				set {
					match-label-list		"loose, strict";

					loose-match-field		"element, interface, ip, channel";
					loose-match-state		"recovery";
					loose-match-action	"clear";

					strict-match-field	"element, interface, ip, protocol, channel";
					strict-match-state	"failure, warning";
					strict-match-action	"clear";
				}
				accept;
			}
		}
		apply-format GUI_FORMAT;
	}

	/*
		This policy takes all existing events displayed by the GUI and checks
		their age; if they are found to be too old, they are removed.
	*/
	policy-statement EXPIRE_GUI_STORAGE {
		/* Expire information after 30 minutes. */
		term EXPIRE_INFORMATION {
			from {
				event		expire;
				state		information;
				age		1800;
			}
			then reject;
		}
		/* Expire information after 15 minutes. */
		term EXPIRE_RECOVERY {
			from {
				event		expire;
				state		recovery;
				age		900;
			}
			then reject;
		}
		/* Expire failures after 7 days. */
		term EXPIRE_FAILURE {
			from {
				event		expire;
				state		[ failure warning ];
				age		172800;
			}
			then reject;
		}
		/* Expire unknown states after 1 week. */
		term EXPIRE_UNKNOWN {
			from {
				event		expire;
				age		604800;
			}
			then reject;
		}
		term EXPIRE_NOTHING {
			then accept;
		}
		apply-format GUI_FORMAT;
	}

	/*
		A sample email notification policy that sends an message to an email address.
	*/
	policy-statement EMAIL_NOTIFICATION {
		/*
			Send an email to the network operator.
		*/
		term NETWORK_OPERATOR {
			then {
				/* Set the email header and body properties to event specific information. */
				set {
				--	to 		"Network Operator <operator@domain.net>";
					subject	@brief@;
					body		@detail@;
				}
			}
		}

		/* 
			This is an email policy-statment, therefore it should adhere the rules
			defined by 'format-statement EMAIL_FORMAT'.
		*/
		apply-format EMAIL_FORMAT;
	}


	/*
		A sample email notification policy that only emails during off-hours
		(non-business hours).
	*/
	policy-statement EMAIL_NOTIFICATION_OFFHOURS {
		/*
			During business hours (09:00 - 16:59, M-F), reject the email.
		*/
		term BUSINESS_HOURS {
			from {
				day-of-week [ Monday Tuesday Wednesday Thursday Friday ];
				begin-time		09:00;
				end-time			17:00;
			}
			then {
				/* Reject email. */
				reject;
			}
		}
		/*
			Send an email to the network operator's email address, on off-hours.
		*/
		term DEFAULT {
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		"Network Operator <page-operator@domain.net>";
					subject	@brief@;
					body		@detail@;
				}
			}
		}

		/* 
			This is an email policy-statment, therefore it should adhere the rules
			defined by 'format-statement EMAIL_FORMAT'.
		*/
		apply-format EMAIL_FORMAT;
	}


	/*
		A sample email notification rotation policy that utilizes the concept of
		business hours, an off-hours on-call paging schedule, and a holiday
		paging schedule.
	*/
	policy-statement EMAIL_NOTIFICATION_ROTATION {
		/*
			During business hours (09:00 - 16:59, M-F), notify the NOC via email.
		*/
		term BUSINESS_HOURS {
			from {
				day-of-week [ Monday Tuesday Wednesday Thursday Friday ];
				end-time			17:00;
				begin-time		09:00;
			}
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to			noc@domain.net;
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}

		/*
			On Monday, for any event that does not occur during business hours,
			notify the on-call engineer.
		*/
		term MONDAY {
			from day-of-week	Monday;
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to			"Monday Engineer <page-monday@domain.net>";
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}

		/*
			On Tuesday, for any event that does not occur during business hours,
			notify the on-call engineer.
		*/
		term TUESDAY {
			from day-of-week	Tuesday;
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		"Tuesday Engineer <page-tuesday@domain.net>";
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}

		/*
			On Wednesday, for any event that does not occur during business hours,
			notify the on-call engineer.
		*/
		term WEDNESDAY {
			from day-of-week	Wednesday;
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		"Wednesday Engineer <page-wednesday@domain.net>";
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}

		/*
			On Thursday, for any event that does not occur during business hours,
			notify the on-call engineer.
		*/
		term THURSDAY {
			from day-of-week	Thursday;
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		"Thursday Engineer <page-thursday@domain.net>";
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}

		/*
			On Friday, for any event that does not occur during business hours,
			notify the on-call engineer.
		*/
		term FRIDAY {
			from day-of-week	Friday;
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		"Friday Engineer <page-friday@domain.net>";
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}

		/*
			On the weekend, notify the on-call engineer.
		*/
		term WEEKEND {
			from day-of-week	[ Saturday Sunday ];
			then {
				/* Notify the appropriate engineer based on the weekend rotation schedule. */
				evaluate {
					policy-statement EMAIL_WEEKEND_SCHEDULE {
						date	@date@;
					}
				}
				next-policy;
			}
		}

		/*
			If the event did not match any other term because of a configuration
			error, perform the default action of paging all engineers.
		*/
		term DEFAULT {
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		"All Engineers <page-all@domain.net>";
					subject	@brief@;
					body	"WARNING: No on-call engineer.\n\n@detail@";
				}
			}
		}

		/* 
			This is an email policy-statment, therefore it should adhere the rules
			defined by 'format-statement EMAIL_FORMAT'.
		*/
		apply-format EMAIL_FORMAT;
	}

	/*
		A sample email notification policy used as a sub-policy to create a holiday paging schedule.
	*/
	policy-statement EMAIL_HOLIDAY_SCHEDULE {
		term CHRISTMAS {
			from date	[ "12/24/03" "12/25/03" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to			"Unlucky Engineer <unlucky@domain.net>";
					subject	@brief@;
					body		"Merry Christmas:\n\n@detail@";
				}
				next-policy;
			}
		}
		term NEW_YEARS {
			from date	[ "12/31/03" "01/01/04" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to			"Sober Engineer <sober@domain.net>";
					subject	@brief@;
					body	"Happy New Years\n\n@detail@";
				}
				next-policy;
			}
		}
		apply-format EMAIL_POLICY_FORMAT;
	}

	/*
		A sample email notification policy used as a sub-policy to create a weekend paging schedule.
	*/
	policy-statement EMAIL_WEEKEND_SCHEDULE {
		term DON {
			from date [ "12/28/02" "12/29/02" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		page-don@domain.net;
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}
		term MIKE {
			from date [ "01/04/03" "01/04/04" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		page-mike@domain.net;
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}
		term CHAD {
			from date [ "01/11/03" "01/12/03" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		page-chad@domain.net;
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}
		term ERIC {
			from date [ "01/18/03" "01/19/03" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		page-eric@domain.net;
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}
		term JIM {
			from date [ "01/25/03" "01/26/03" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		page-jim@domain.net;
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}
		term BILL {
			from date [ "02/01/03" "02/02/03" ];
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to 		page-bill@domain.net;
					subject	@brief@;
					body		@detail@;
				}
				next-policy;
			}
		}
		term DEFAULT {
			then {
				/* Set the email header and body properties to event specific information. */
				set {
					to			page-all@domain.net;
					subject	@brief@;
					body		"WARNING: no on-call engineer.\n\n@detail@";
				}
				next-policy;
			}
		}
		apply-format EMAIL_POLICY_FORMAT;
	}

}

/*
** Local Variables:
** c-basic-offset: 3
** tab-width: 3
** End:
** vim600: fdm=marker
** vim: noet ts=3 sw=3
** vim: syntax=sella_nms
*/
