<?xml version="1.0" encoding="utf-8"?>
<!--
     Firewall Builder Document Type Definition
     http://www.fwbuilder.org/
     Version: $Revision: 1023 $
     Authors:  Friedhelm Duesterhoeft, Vadim Zaliva, Vadim Kurland, Tidei Maurizio

TODO:

1. Allow groups of unrelated objects.

-->

<!ENTITY % BOOLEAN   "(False|True)">
<!ENTITY % STRING    "CDATA">
<!ENTITY % NUMBER    "CDATA">

<!--
 * Supported policy rule actions:
 *
 *        Accept - accept the packet, analysis terminates
 *
 *        Reject - reject the packet and send ICMP 'unreachable' or
 *                 TCP RST back to sender, analysis terminates
 *
 *        Deny   - drop the packet, nothing is sent back to sender,
 *                 analysis terminates
 *
 *        Scrub  - run the packet through normalizer (see 'scrub' in
 *                 PF), continue analysis
 *
 *        Return - action used internally, meaning may depend on
 *                 implementation of the policy compiler but generally 
 *                 means return from the block of rules
 *
 *        Skip   - skip N rules down and continue analysis. Used
 *                 internally.
 *
 *        Continue - do nothing, continue analysis. Used internally.
 *
 *        Accounting - generate target firewall platform rule to count
 *                 the packet and continue analysis.
 *
 *        Modify - edit the packet (change some header values, like
 *                 TOS bits) or mark it somehow if the kernel supports 
 *                 that (e.g. target MARK in iptables)
 *
 *        Tag    - put a tag on the packet or mark it somehow
 *        
 *        Pipe   - send the packet to the userland process for inspection
 *        
 *        Classify - classify the packet for QoS or traffic shaping
 * 
 *        Custom - platform-depended custom action
 *
 *        Branch - branch to a subset of rules for inspection
 *
-->

<!ENTITY % ACTION "(Accept|Reject|Deny|Scrub|Return|Skip|Continue|Accounting|Modify|Tag|Pipe|Classify|Custom|Branch|Route)">
<!ENTITY % NAT_ACTION "(Translate|NATBranch)">
<!ENTITY % DIRECTION "(Inbound|Outbound|Both)">
<!ENTITY % IPADDRESS "CDATA">
<!ENTITY % NETMASK "CDATA">
<!ENTITY % IP6ADDRESS "CDATA">
<!ENTITY % IP6NETMASK "CDATA">

<!-- Standard attributes presented in all nodes -->
<!ENTITY % STD_ATTRIBUTES '
 name    %STRING;  #REQUIRED
 comment %STRING;  #IMPLIED
 id      ID        #REQUIRED
 ro      %BOOLEAN; #IMPLIED
'>

<!-- Standard attributes for all system nodes -->
<!ENTITY % SYS_ATTRIBUTES '
'>

<!-- 
      **** Document structure, main groups. ****
-->

<!ELEMENT FWObjectDatabase (Library*)>
<!ATTLIST FWObjectDatabase
 xmlns        CDATA     #FIXED "http://www.fwbuilder.org/1.0/"
 version      %STRING;  #FIXED "17"
 lastModified %NUMBER;  #IMPLIED
 id           ID        #REQUIRED
>

<!ELEMENT Library
((AnyNetwork|AnyIPService|AnyInterval|ObjectGroup|StateSyncClusterGroup|FailoverClusterGroup|Host|Firewall|Cluster|Network|NetworkIPv6|IPv4|IPv6|DNSName|AddressTable|physAddress|AddressRange|ObjectRef|ServiceGroup|IPService|ICMPService|ICMP6Service|TCPService|UDPService|CustomService|ServiceRef|IntervalGroup|Interval|IntervalRef|Interface|Policy|NAT|PolicyRule|NATRule|Library|TagService|UserService)*)>
<!ATTLIST Library
 %STD_ATTRIBUTES;
 color   %STRING;  #IMPLIED
>


<!-- 
      **** Document structure, Services. ****
-->

<!ELEMENT AnyIPService EMPTY>
<!ATTLIST AnyIPService
 %SYS_ATTRIBUTES;
 %STD_ATTRIBUTES;
 protocol_num %NUMBER;  #FIXED     "0"
>

<!-- Reference to Services child -->
<!ELEMENT ServiceRef EMPTY>
<!ATTLIST ServiceRef 
       ref IDREF #REQUIRED
>

<!ELEMENT ServiceGroup (( ServiceGroup | IPService | ICMPService  | ICMP6Service  | TCPService | UDPService | CustomService | ServiceRef | TagService | UserService)*)>
<!ATTLIST ServiceGroup
 %STD_ATTRIBUTES;
>

<!-- 
      **** Document structure, Objects. ****
-->

<!-- Reference to Objects child -->
<!ELEMENT ObjectRef EMPTY>
<!ATTLIST ObjectRef 
       ref IDREF #REQUIRED
>

<!ELEMENT ObjectGroup ((ObjectGroup|Host|Firewall|Cluster|Network|NetworkIPv6|IPv4|IPv6|DNSName|AddressTable|AddressRange|ObjectRef)*)>
<!ATTLIST ObjectGroup
 %STD_ATTRIBUTES;
>

<!--
      **** Document structure, Cluster members. ****
-->

<!ELEMENT StateSyncClusterGroup (ObjectRef*, ClusterGroupOptions?)>
<!ATTLIST StateSyncClusterGroup
 %STD_ATTRIBUTES;
 type         %STRING; #REQUIRED
 master_iface IDREF    #IMPLIED
>

<!ELEMENT FailoverClusterGroup (ObjectRef*, ClusterGroupOptions?)>
<!ATTLIST FailoverClusterGroup
 %STD_ATTRIBUTES;
 type         %STRING; #REQUIRED
 master_iface IDREF    #IMPLIED
>


<!-- 

This element will contain elements with platform  specific
options.

<Options>
    <Option name="option1_name">Value1</Option>
    <Option name="option2_name">Value2</Option>
</Options>

Since list of compilers is open (everybody could write his
own compiler) we do not define content model for this element.

-->

<!ELEMENT Option ANY>
<!ATTLIST Option
 name %STRING; #REQUIRED
>


<!ELEMENT PolicyRuleOptions (Option*)>
<!ELEMENT NATRuleOptions    (Option*)>
<!ELEMENT RoutingRuleOptions (Option*)>
<!ELEMENT FirewallOptions   (Option*)>
<!ELEMENT InterfaceOptions  (Option*)>
<!ELEMENT HostOptions       (Option*)>
<!ELEMENT GatewayOptions    (Option*)>
<!ELEMENT ClusterGroupOptions (Option*)>
<!ELEMENT RuleSetOptions    (Option*)>

<!-- 
      **** Document structure, rest ****
-->

<!ELEMENT NATRule (OSrc,ODst,OSrv,TSrc,TDst,TSrv,When?, NATRuleOptions?)>
<!ATTLIST NATRule
 id      ID       #REQUIRED
 action    %NAT_ACTION; #REQUIRED
 disabled  %BOOLEAN;   "False"
 position  %NUMBER;    #REQUIRED
 comment   %STRING;    #IMPLIED
 group     %STRING;    #IMPLIED
>

<!ELEMENT When (IntervalRef*)>
<!ATTLIST When
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT OSrc (ObjectRef*)>
<!ATTLIST OSrc
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT ODst (ObjectRef*)>
<!ATTLIST ODst
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT OSrv (ServiceRef*)>
<!ATTLIST OSrv
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT TSrc (ObjectRef*)>
<!ATTLIST TSrc
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT TDst (ObjectRef*)>
<!ATTLIST TDst
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT TSrv (ServiceRef*)>
<!ATTLIST TSrv
 neg %BOOLEAN; #REQUIRED
>


<!ELEMENT RoutingRule (RDst,RGtw,RItf, RoutingRuleOptions?, Routing?)>
<!ATTLIST RoutingRule
 id      ID       #REQUIRED
 disabled  %BOOLEAN;   "False"
 position  %NUMBER;    #REQUIRED
 metric    %NUMBER;    "0"
 comment   %STRING;    #IMPLIED
 group     %STRING;    #IMPLIED
>

<!ELEMENT RDst (ObjectRef*)>
<!ATTLIST RDst
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT RGtw (ObjectRef*)>
<!ATTLIST RGtw
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT RItf (ObjectRef*)>
<!ATTLIST RItf
 neg %BOOLEAN; #REQUIRED
>


<!ELEMENT PolicyRule (Src,Dst,Srv?,Itf?,When?,PolicyRuleOptions?)>
<!ATTLIST PolicyRule
 id       ID       #REQUIRED
 disabled  %BOOLEAN;   "False"
 position  %NUMBER;    #REQUIRED
 direction %DIRECTION; #IMPLIED
 action    %ACTION;    #REQUIRED
 log       %BOOLEAN;   #REQUIRED
 comment   %STRING;    #IMPLIED
 group     %STRING;    #IMPLIED
>

<!ELEMENT Src (ObjectRef*)>
<!ATTLIST Src
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT Dst (ObjectRef*)>
<!ATTLIST Dst
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT Srv (ServiceRef*)>
<!ATTLIST Srv
 neg %BOOLEAN; #REQUIRED
>

<!ELEMENT Itf (ObjectRef*)>
<!ATTLIST Itf
 neg %BOOLEAN; #REQUIRED
>


<!--
   hardware or physical address (MAC, DLCI etc.)
-->
<!ELEMENT physAddress EMPTY>
<!ATTLIST physAddress
 %STD_ATTRIBUTES;
 address %STRING; #REQUIRED
>

<!ELEMENT IPv4 EMPTY>
<!ATTLIST IPv4
 %STD_ATTRIBUTES;
 address %IPADDRESS; #REQUIRED
 netmask %NETMASK;   #REQUIRED
>

<!ELEMENT IPv6 EMPTY>
<!ATTLIST IPv6
 %STD_ATTRIBUTES;
 address %IP6ADDRESS; #REQUIRED
 netmask %IP6NETMASK; #REQUIRED
>

<!ELEMENT DNSName EMPTY>
<!ATTLIST DNSName
 %STD_ATTRIBUTES;
 dnsrec         %STRING;    #REQUIRED
 dnsrectype     %STRING;    #IMPLIED
 run_time       %BOOLEAN;   #REQUIRED
>

<!ELEMENT AddressTable ((IPv4|IPv6|ObjectRef)*)>
<!ATTLIST AddressTable
 %STD_ATTRIBUTES;
 filename       %STRING;    #REQUIRED
 run_time       %BOOLEAN;   #REQUIRED
>
<!--
Interface can have the following attributes:

   - dyn            interface has dynamically assigned address
   - unnum          interface is unnumbered (does not have IP address, but 
                    may still have MAC address)
   - bridgeport     interface serves as a bridge port on bridging firewall.
                    The difference between bridge port and unnumbered interface
                    is that compilers may use special modules or commands for
                    bridge ports on platforms that support them, such as 
                    module physdev for iptables.
   - mgmt           this is management interface
   - physAddress    MAC address of this interface
   - security_level
   - network_zone   ID of the object representing network zone
   - unprotected    Skip this interface while assigning access lists or policy rules
   - dedicated_failover Specialized version of "unprotected"
   - label          human-readable label of this interface

-->
<!ELEMENT Interface (IPv4*, IPv6*, physAddress?, InterfaceOptions?, Interface*, FailoverClusterGroup?)>
<!ATTLIST Interface
 %STD_ATTRIBUTES;
 dyn            %BOOLEAN;   #REQUIRED
 unnum          %BOOLEAN;   #IMPLIED
 mgmt           %BOOLEAN;   #IMPLIED
 bridgeport     %BOOLEAN;   #IMPLIED
 security_level %NUMBER;    #REQUIRED
 network_zone   IDREF       #IMPLIED
 unprotected    %BOOLEAN;   #IMPLIED
 dedicated_failover %BOOLEAN; #IMPLIED
 label          %STRING;    #IMPLIED
>


<!-- Remote management information for Firewall, Host, Gateway  -->
<!ELEMENT Management (SNMPManagement? , FWBDManagement?, PolicyInstallScript?)>
<!ATTLIST Management
 address              %IPADDRESS; #REQUIRED
>

<!-- User-defined custom policy installation script for Firewall  -->
<!ELEMENT PolicyInstallScript EMPTY>
<!ATTLIST PolicyInstallScript
 enabled   %BOOLEAN;  "False"
 command   %STRING;    #IMPLIED
 arguments %STRING;    #IMPLIED
>

<!-- SNMP management information for Firewall, Host, Gateway  -->
<!ELEMENT SNMPManagement EMPTY>
<!ATTLIST SNMPManagement
 enabled  %BOOLEAN;  "False"
 snmp_read_community  %STRING;    #IMPLIED
 snmp_write_community %STRING;    #IMPLIED
>

<!-- FWBD management information for Firewall, Host, Gateway  -->
<!ELEMENT FWBDManagement (PublicKey?)>
<!ATTLIST FWBDManagement
 enabled  %BOOLEAN;  "False"
 port                 %NUMBER;    #REQUIRED
 identity             %STRING;    #REQUIRED
>

<!-- Remote FWBD public key for Firewall, Host, Gateway  -->
<!ELEMENT PublicKey (#PCDATA)>

<!ELEMENT Host (Interface*, Management?, HostOptions?)>
<!ATTLIST Host
 %STD_ATTRIBUTES;
 host_OS              %STRING;    #IMPLIED
>

<!ELEMENT AnyNetwork EMPTY>
<!ATTLIST AnyNetwork
 %SYS_ATTRIBUTES;
 %STD_ATTRIBUTES;
 address              %IPADDRESS; #FIXED    "0.0.0.0"
 netmask              %NETMASK;   #FIXED    "0.0.0.0"
>

<!ELEMENT Network EMPTY>
<!ATTLIST Network
 %STD_ATTRIBUTES;
 address %IPADDRESS; #REQUIRED
 netmask %NETMASK;   #REQUIRED
>

<!ELEMENT NetworkIPv6 EMPTY>
<!ATTLIST NetworkIPv6
 %STD_ATTRIBUTES;
 address %IPADDRESS; #REQUIRED
 netmask %NETMASK;   #REQUIRED
>

<!ELEMENT AddressRange EMPTY>
<!ATTLIST AddressRange
 %STD_ATTRIBUTES;
 start_address %IPADDRESS; #REQUIRED
 end_address   %IPADDRESS; #REQUIRED
>

<!ELEMENT ICMPService EMPTY>
<!ATTLIST ICMPService
 %STD_ATTRIBUTES;
 code %NUMBER; #REQUIRED
 type %NUMBER; #REQUIRED
>

<!ELEMENT ICMP6Service EMPTY>
<!ATTLIST ICMP6Service
 %STD_ATTRIBUTES;
 code %NUMBER; #REQUIRED
 type %NUMBER; #REQUIRED
>


<!ELEMENT TagService EMPTY>
<!ATTLIST TagService
 %STD_ATTRIBUTES;
 tagcode %STRING;  #REQUIRED
>

<!--     
See definition of IP options here: http://www.iana.org/assignments/ip-parameters

router-alert option is defined in RFC2113. This option carries 16 bit value
although only value "0" is defined at this time, all other values are
reserved. Used in RSVP and IGMP2 protocols.

attribute "any_opt" is used to create IPService object to match IP packets
with any options present. Some firewall platforms can do this (pf, iptables),
some can't (ipfilter, IOS, PIX)
-->
<!ELEMENT IPService EMPTY>
<!ATTLIST IPService
 %STD_ATTRIBUTES;
 protocol_num %NUMBER;  #REQUIRED
 fragm        %BOOLEAN; #IMPLIED
 any_opt      %BOOLEAN; #IMPLIED
 lsrr         %BOOLEAN; #IMPLIED
 rr           %BOOLEAN; #IMPLIED
 short_fragm  %BOOLEAN; #IMPLIED
 ssrr         %BOOLEAN; #IMPLIED
 ts           %BOOLEAN; #IMPLIED
 tos          %STRING;  #IMPLIED
 dscp         %STRING;  #IMPLIED
 rtralt       %BOOLEAN; #IMPLIED
 rtralt_value %NUMBER;  #IMPLIED
>

<!ELEMENT TCPService EMPTY>
<!ATTLIST TCPService
 %STD_ATTRIBUTES;
 dst_range_end   %NUMBER;  #REQUIRED
 dst_range_start %NUMBER;  #REQUIRED
 urg_flag        %BOOLEAN; #REQUIRED
 ack_flag        %BOOLEAN; #REQUIRED
 psh_flag        %BOOLEAN; #REQUIRED
 rst_flag        %BOOLEAN; #REQUIRED
 syn_flag        %BOOLEAN; #REQUIRED
 fin_flag        %BOOLEAN; #REQUIRED
 urg_flag_mask   %BOOLEAN; #REQUIRED
 ack_flag_mask   %BOOLEAN; #REQUIRED
 psh_flag_mask   %BOOLEAN; #REQUIRED
 rst_flag_mask   %BOOLEAN; #REQUIRED
 syn_flag_mask   %BOOLEAN; #REQUIRED
 fin_flag_mask   %BOOLEAN; #REQUIRED
 src_range_end   %NUMBER;  #REQUIRED
 src_range_start %NUMBER;  #REQUIRED
 established     %BOOLEAN; #IMPLIED
>

<!ELEMENT UDPService EMPTY>
<!ATTLIST UDPService
 %STD_ATTRIBUTES;
 dst_range_end   %NUMBER; #REQUIRED
 dst_range_start %NUMBER; #REQUIRED
 src_range_end   %NUMBER; #REQUIRED
 src_range_start %NUMBER; #REQUIRED
>

<!ELEMENT CustomServiceCommand (#PCDATA)>
<!ATTLIST CustomServiceCommand
 platform %STRING; #REQUIRED
>

<!ELEMENT CustomService  (CustomServiceCommand*)>
<!ATTLIST CustomService
 %STD_ATTRIBUTES;
 protocol       %STRING;    #IMPLIED
 address_family %STRING;    #IMPLIED
>

<!ELEMENT UserService EMPTY>
<!ATTLIST UserService
 %STD_ATTRIBUTES;
 userid       %STRING;    #REQUIRED
>

<!ELEMENT Gateway (Interface* , Management?, GatewayOptions?)>
<!ATTLIST Gateway
 %STD_ATTRIBUTES;
 address              %IPADDRESS; #REQUIRED
 host_OS              %STRING;    #IMPLIED
>

<!ELEMENT Firewall (NAT* , Policy* , Routing , Interface* , Management?, FirewallOptions?)>
<!ATTLIST Firewall
 %STD_ATTRIBUTES;
 platform             %STRING;    #REQUIRED
 version              %STRING;    #IMPLIED
 host_OS              %STRING;    #IMPLIED
 lastModified         %NUMBER;    #IMPLIED
 lastInstalled        %NUMBER;    #IMPLIED
 lastCompiled         %NUMBER;    #IMPLIED
 inactive             %BOOLEAN;   #IMPLIED
>

<!ELEMENT Cluster (NAT*, Policy*, Routing, Interface*, Management?, FirewallOptions?, StateSyncClusterGroup*)>
<!ATTLIST Cluster
 %STD_ATTRIBUTES;
 platform             %STRING;    #REQUIRED
 host_OS              %STRING;    #IMPLIED
 lastModified         %NUMBER;    #IMPLIED
 lastInstalled        %NUMBER;    #IMPLIED
 lastCompiled         %NUMBER;    #IMPLIED
 inactive             %BOOLEAN;   #IMPLIED
>

<!ELEMENT NAT (NATRule*, RuleSetOptions)>
<!ATTLIST NAT
 %STD_ATTRIBUTES;
 ipv4_rule_set       %BOOLEAN; #IMPLIED
 ipv6_rule_set       %BOOLEAN; #IMPLIED
 top_rule_set        %BOOLEAN; #IMPLIED
>

<!ELEMENT Policy (PolicyRule*, RuleSetOptions)>
<!ATTLIST Policy
 %STD_ATTRIBUTES;
 ipv4_rule_set       %BOOLEAN; #IMPLIED
 ipv6_rule_set       %BOOLEAN; #IMPLIED
 top_rule_set        %BOOLEAN; #IMPLIED
>

<!ELEMENT Routing (RoutingRule*, RuleSetOptions)>
<!ATTLIST Routing
 %STD_ATTRIBUTES;
 ipv4_rule_set       %BOOLEAN; #IMPLIED
 ipv6_rule_set       %BOOLEAN; #IMPLIED
 top_rule_set        %BOOLEAN; #IMPLIED
>


<!-- Time -->

<!ELEMENT IntervalGroup ((IntervalGroup|Interval|IntervalRef)*)>
<!ATTLIST IntervalGroup
 %STD_ATTRIBUTES;
>

<!-- Reference to time interval -->
<!ELEMENT IntervalRef EMPTY>
<!ATTLIST IntervalRef 
       ref IDREF #REQUIRED
>

<!-- up until fwbuilder3 this element used two separate attributes
 to deal with days of week, one for the start day of week and another
 for the end day of week. Starting with fwbuilder3 we support iptables 1.4.0
 module "time" which allows for random day of week spec. Fwbuilder3 
 provides support for that in object Interval, which uses attrbute
 days_of_week in this element. Need to phase out attributes from_weekday
 and to_weekday some time in the future.
-->
<!ELEMENT Interval EMPTY>
<!ATTLIST Interval
 %STD_ATTRIBUTES;
 from_second  %NUMBER; "-1"
 from_minute  %NUMBER; "-1"
 from_hour    %NUMBER; "-1"
 from_day     %NUMBER; "-1"
 from_month   %NUMBER; "-1"
 from_year    %NUMBER; "-1"
 from_weekday %NUMBER; "-1"

 to_second    %NUMBER; "-1"
 to_minute    %NUMBER; "-1"
 to_hour      %NUMBER; "-1"
 to_day       %NUMBER; "-1"
 to_month     %NUMBER; "-1"
 to_year      %NUMBER; "-1"
 to_weekday   %NUMBER; "-1"

 days_of_week %STRING; #IMPLIED
>

<!ELEMENT AnyInterval EMPTY>
<!ATTLIST AnyInterval
 %SYS_ATTRIBUTES;
 %STD_ATTRIBUTES;
 from_second  %NUMBER; #FIXED "-1"
 from_minute  %NUMBER; #FIXED "-1"
 from_hour    %NUMBER; #FIXED "-1"
 from_day     %NUMBER; #FIXED "-1"
 from_month   %NUMBER; #FIXED "-1"
 from_year    %NUMBER; #FIXED "-1"
 from_weekday %NUMBER; #FIXED "-1"

 to_second    %NUMBER; #FIXED "-1"
 to_minute    %NUMBER; #FIXED "-1"
 to_hour      %NUMBER; #FIXED "-1"
 to_day       %NUMBER; #FIXED "-1"
 to_month     %NUMBER; #FIXED "-1"
 to_year      %NUMBER; #FIXED "-1"
 to_weekday   %NUMBER; #FIXED "-1"

 days_of_week %STRING; #IMPLIED
>

