In article , wrote: :I copied this statement from a Cisco training tutorial I just browsed. :The last sentence in the paragraph is not very clear to me. Would one :of you PIX experts explain it in english please.
It -is- in English, and if it does not happen to be clear, then it is probably best re-explained in algorithm form.
:In software versions 5.2 and higher, for all inbound traffic, the PIX :Firewall
return if ( PIX_major_version < 5 || PIX_minor_version < 2 );
:denies translations for destination IP addresses identified as :network addresses or broadcast addresses.
:It uses the global IP and :mask from a static command statement to differentiate regular IP :addresses from network or broadcast addresses. If a global IP address :is a valid network address with a matching network mask, then the PIX :Firewall disallows the xlate for network or broadcast IP addresses with :inbound packet.
/* the following mostly ignores IPv6 for brevity */
typedef enum { Unset_Address, IPv4_Address, IPv6_Address } address_variety_e;
typedef struct { address_variety_e address_variety; union { IPv4_address_t ipv4_address; IPv6_address_t ipv6_address; } ip_address; } ip_address_t;
typedef struct { ip_address_t ip; ip_address_t mask; } ip_and_mask_t;
typedef struct { logical interface_active; ip_and_mask_t ip_and_mask; other_interface_info_t other_interface_info; } interface_table_entry_t;
ip_address_t find_base_address( ip_and_mask_t ip_addr ) { ip_address_t base_address; if ( ip_addr.ip.address_variety == Unset_Address ) { base_address.address_variety = Unset_Address; base_address.ipv4_address = 0; return base_address; } else if ( ip_addr.ip.address_variety == IPv4_Address ) { base_address.address_variety = IPv4_Address; base_address.ipv4_address = ip_addr.ip.ipv4_address & ~ip_addr.mask.ipv4_address; return base_address; } else { ... } }
ip_address_t find_broadcast_address( ip_and_mask_t ip_addr ) { ip_address_t broad_address; if ( ip_addr.ip.address_variety == Unset_Address ) { broad_address.address_variety = Unset_Address; broad_address.ipv4_address = ~0; return broad_address; } else if ( ip_addr.ip.address_variety == IPv4_Address ) { broad_address.address_variety = IPv4_Address; broad_address.ipv4_address = ip_addr.ip.ipv4_address | ~ip_addr.mask.ipv4_address; return broad_address; } else { ... } }
typedef enum { Unset_static, Network_static, Port_static, Policy_static, } static_variety_e;
/* The following structure ignores policy statics and ignores the details of matching against the right interface -- it assumes a simple two-interface model
*/
typedef struct static_table_entry_s { struct static_table_entry_s *next_entry; static_variety_e static_variety; ip_and_mask_t outside_ip_and_mask; ip_and_mask_t inside_ip_and_mask; uint16_t outside_port; uint16_t inside_port; } static_table_entry_t;
logical is_network_address(ip_address_t ip_addr) { extern interface_table_entry_t interface_table[MAX_INTERFACES]; extern static_table_entry_t *static_table;
int tab_idx; static_table_entry_t *static_tab_ptr;
for (tab_idx = 0; tab_idx < MAX_INTERFACES; tab_idx++ ) { if ( interface_table[tab_idx].is_active && ip_addr == find_base_address( interface_table[tab_idx].ip_and_mask ) ) { return TRUE; } }
for ( static_tab_ptr = static_table; static_tab_ptr != NULL; static_tab_ptr = static_tab_ptr->next_entry; ) { if ( static_tab_ptr->static_variety == Network_static && find_base_address( static_tab_ptr->outside_ip_and_mask ) != find_broad_address( static_tab_ptr->outside_ip_and_mask ) && ip_addr == find_base_address( static_tab_ptr->outside_ip_and_mask ) ) { return TRUE; } else if ( static_tab_ptr->static_variety == Port_static ) { /* left as an exercise for the reader */ } }
return FALSE; }
logical is_broad_address(ip_address_t ip_addr) { extern interface_table_entry_t interface_table[MAX_INTERFACES]; extern static_table_entry_t *static_table;
int tab_idx; static_table_entry_t *static_tab_ptr;
for (tab_idx = 0; tab_idx < MAX_INTERFACES; tab_idx++ ) { if ( interface_table[tab_idx].is_active && ip_addr == find_broad_address( interface_table[tab_idx].ip_and_mask ) ) { return TRUE; } }
for ( static_tab_ptr = static_table; static_tab_ptr != NULL; static_tab_ptr = static_tab_ptr->next_entry; ) { if ( static_tab_ptr->static_variety == Network_static && find_base_address( static_tab_ptr->outside_ip_and_mask ) != find_broad_address( static_tab_ptr->outside_ip_and_mask ) && ip_addr == find_broad_address( static_tab_ptr->outside_ip_and_mask ) ) { return TRUE; } else if ( static_tab_ptr->static_variety == Port_static ) { /* left as an exercise for the reader */ } }
return FALSE; }
logical xlate_allowed( whatever ) { ... if ( packet_direction == inbound && (is_network_address(destination) || is_broadcast_address(destination)) ) { return FALSE; } ... }