require '_h2ph_pre.ph';

no warnings qw(redefine misc);

unless(defined(&_NET_IF_ETHER_H_)) {
    eval 'sub _NET_IF_ETHER_H_ () {1;}' unless defined(&_NET_IF_ETHER_H_);
    if(defined(&_KERNEL)) {
	if(defined(&_KERNEL_OPT)) {
	    require './net/opt_mbuftrace.ph';
	}
	require 'sys/mbuf.ph';
    }
    unless(defined(&_STANDALONE)) {
	require 'net/if.ph';
    }
    eval 'sub ETHER_ADDR_LEN () {6;}' unless defined(&ETHER_ADDR_LEN);
    eval 'sub ETHER_TYPE_LEN () {2;}' unless defined(&ETHER_TYPE_LEN);
    eval 'sub ETHER_CRC_LEN () {4;}' unless defined(&ETHER_CRC_LEN);
    eval 'sub ETHER_HDR_LEN () {(( &ETHER_ADDR_LEN * 2) +  &ETHER_TYPE_LEN);}' unless defined(&ETHER_HDR_LEN);
    eval 'sub ETHER_MIN_LEN () {64;}' unless defined(&ETHER_MIN_LEN);
    eval 'sub ETHER_MAX_LEN () {1518;}' unless defined(&ETHER_MAX_LEN);
    eval 'sub ETHER_MAX_LEN_JUMBO () {9018;}' unless defined(&ETHER_MAX_LEN_JUMBO);
    eval 'sub ETHER_VLAN_ENCAP_LEN () {4;}' unless defined(&ETHER_VLAN_ENCAP_LEN);
    eval 'sub EVL_VLANOFTAG {
        my($tag) = @_;
	    eval q((($tag) & 4095));
    }' unless defined(&EVL_VLANOFTAG);
    eval 'sub EVL_PRIOFTAG {
        my($tag) = @_;
	    eval q(((($tag) >> 13) & 7));
    }' unless defined(&EVL_PRIOFTAG);
    eval 'sub EVL_CFIOFTAG {
        my($tag) = @_;
	    eval q(((($tag) >> 12) & 1));
    }' unless defined(&EVL_CFIOFTAG);
    eval 'sub ETHER_PPPOE_ENCAP_LEN () {8;}' unless defined(&ETHER_PPPOE_ENCAP_LEN);
    eval 'sub ETHER_ALIGN () {2;}' unless defined(&ETHER_ALIGN);
    require 'net/ethertypes.ph';
    eval 'sub ETHER_IS_MULTICAST {
        my($addr) = @_;
	    eval q((*($addr) & 0x1));
    }' unless defined(&ETHER_IS_MULTICAST);
    eval 'sub ETHER_IS_LOCAL {
        my($addr) = @_;
	    eval q((*($addr) & 0x2));
    }' unless defined(&ETHER_IS_LOCAL);
    eval 'sub ETHERMTU_JUMBO () {( &ETHER_MAX_LEN_JUMBO -  &ETHER_HDR_LEN -  &ETHER_CRC_LEN);}' unless defined(&ETHERMTU_JUMBO);
    eval 'sub ETHERMTU () {( &ETHER_MAX_LEN -  &ETHER_HDR_LEN -  &ETHER_CRC_LEN);}' unless defined(&ETHERMTU);
    eval 'sub ETHERMIN () {( &ETHER_MIN_LEN -  &ETHER_HDR_LEN -  &ETHER_CRC_LEN);}' unless defined(&ETHERMIN);
    eval 'sub ETHER_MAX_FRAME {
        my($ifp, $etype, $hasfcs) = @_;
	    eval q((($ifp)-> &if_mtu +  &ETHER_HDR_LEN + (($hasfcs) ?  &ETHER_CRC_LEN : 0) + ((($etype) ==  &ETHERTYPE_VLAN) ?  &ETHER_VLAN_ENCAP_LEN : 0) + ((($etype) ==  &ETHERTYPE_PPPOE) ?  &ETHER_PPPOE_ENCAP_LEN : 0)));
    }' unless defined(&ETHER_MAX_FRAME);
    eval 'sub ETHER_CRC_POLY_LE () {0xedb88320;}' unless defined(&ETHER_CRC_POLY_LE);
    eval 'sub ETHER_CRC_POLY_BE () {0x4c11db6;}' unless defined(&ETHER_CRC_POLY_BE);
    unless(defined(&_STANDALONE)) {
	eval 'sub M_HASFCS () { &M_LINK0;}' unless defined(&M_HASFCS);
	eval 'sub M_PROMISC () { &M_LINK1;}' unless defined(&M_PROMISC);
	if(defined(&_KERNEL)) {
	    eval 'sub ETHER_MAP_IP_MULTICAST {
	        my($ipaddr, $enaddr) = @_;
    		eval q( &do { ($enaddr)[0] = 0x1; ($enaddr)[1] = 0x; ($enaddr)[2] = 0x5e; ($enaddr)[3] = (( &const  &uint8_t *)$ipaddr)[1] & 0x7f; ($enaddr)[4] = (( &const  &uint8_t *)$ipaddr)[2]; ($enaddr)[5] = (( &const  &uint8_t *)$ipaddr)[3]; }  &while ( 0));
	    }' unless defined(&ETHER_MAP_IP_MULTICAST);
	    eval 'sub ETHER_MAP_IPV6_MULTICAST {
	        my($ip6addr, $enaddr) = @_;
    		eval q({ ($enaddr)[0] = 0x33; ($enaddr)[1] = 0x33; ($enaddr)[2] = (( &const  &uint8_t *)$ip6addr)[12]; ($enaddr)[3] = (( &const  &uint8_t *)$ip6addr)[13]; ($enaddr)[4] = (( &const  &uint8_t *)$ip6addr)[14]; ($enaddr)[5] = (( &const  &uint8_t *)$ip6addr)[15]; });
	    }' unless defined(&ETHER_MAP_IPV6_MULTICAST);
	}
	if(defined(&MBUFTRACE)) {
	}
	eval 'sub ETHERCAP_VLAN_MTU () {0x1;}' unless defined(&ETHERCAP_VLAN_MTU);
	eval 'sub ETHERCAP_VLAN_HWTAGGING () {0x2;}' unless defined(&ETHERCAP_VLAN_HWTAGGING);
	eval 'sub ETHERCAP_JUMBO_MTU () {0x4;}' unless defined(&ETHERCAP_JUMBO_MTU);
	eval 'sub ETHERCAP_VLAN_HWFILTER () {0x8;}' unless defined(&ETHERCAP_VLAN_HWFILTER);
	eval 'sub ETHERCAP_EEE () {0x10;}' unless defined(&ETHERCAP_EEE);
	eval 'sub ETHERCAP_MASK () {0x1f;}' unless defined(&ETHERCAP_MASK);
	eval 'sub ECCAPBITS () {"\\020" "\\1VLAN_MTU" "\\2VLAN_HWTAGGING" "\\3JUMBO_MTU" "\\4VLAN_HWFILTER" "\\5EEE";}' unless defined(&ECCAPBITS);
	if(defined(&_KERNEL)) {
	    eval 'sub ETHER_F_ALLMULTI () { &__BIT(0);}' unless defined(&ETHER_F_ALLMULTI);
	    eval 'sub ETHER_NEXT_MULTI {
	        my($step, $enm) = @_;
    		eval q(($enm) =  &ether_next_multi(($step)));
	    }' unless defined(&ETHER_NEXT_MULTI);
	    eval 'sub ether_first_multi {
	        my($step,$ec) = @_;
    		eval q({  ($step->{e_enm}) =  &LIST_FIRST( ($ec->{ec_multiaddrs}));  &ether_next_multi($step); });
	    }' unless defined(&ether_first_multi);
	    eval 'sub ETHER_FIRST_MULTI {
	        my($step, $ec, $enm) = @_;
    		eval q(($enm) =  &ether_first_multi(($step), ($ec)));
	    }' unless defined(&ETHER_FIRST_MULTI);
	    eval 'sub ETHER_LOCK {
	        my($ec) = @_;
    		eval q( &mutex_enter(($ec)-> &ec_lock));
	    }' unless defined(&ETHER_LOCK);
	    eval 'sub ETHER_UNLOCK {
	        my($ec) = @_;
    		eval q( &mutex_exit(($ec)-> &ec_lock));
	    }' unless defined(&ETHER_UNLOCK);
	    eval 'sub vlan_has_tag {
	        my($m) = @_;
    		eval q({ ( ($m->{m_flags}) &  &M_VLANTAG) != 0; });
	    }' unless defined(&vlan_has_tag);
	    eval 'sub vlan_is_hwtag_enabled {
	        my($_ifp) = @_;
    		eval q({ \'struct ethercom\' * &ec = ( &void *)$_ifp;  &if ( ($ec->{ec_capenable}) &  &ETHERCAP_VLAN_HWTAGGING)  &true;  &false; });
	    }' unless defined(&vlan_is_hwtag_enabled);
	    eval 'sub VLAN_ATTACHED {
	        my($ec) = @_;
    		eval q((($ec)-> &ec_nvlans > 0));
	    }' unless defined(&VLAN_ATTACHED);
	} else {
	    require 'sys/cdefs.ph';
	}
    }
}
1;
