/************************************************************************
* NAME: fnet_igmp_leave
*
* DESCRIPTION: Sends a Leave Group message.
*************************************************************************/
void fnet_igmp_leave( fnet_netif_t *netif, fnet_ip4_addr_t  group_addr )
{
#if FNET_CFG_IGMP_VERSION == 2 
    fnet_netbuf_t *nb_header;
    fnet_igmp_header_t *igmp_header;
    fnet_ip4_addr_t dest_ip = FNET_IP4_ADDR_INIT(224, 0, 0, 2); /* All-routers multicast group.*/
    
    /* Construct IGMP header*/
    if((nb_header = fnet_netbuf_new(sizeof(fnet_igmp_header_t), FNET_FALSE)) != 0)
    {
        /*
         * When a host leaves a multicast group, if it was the last host to
         * reply to a Query with a Membership Report for that group, it SHOULD
         * send a Leave Group message to the all-routers multicast group (224.0.0.2).
         */

        igmp_header = nb_header->data_ptr;
        
        igmp_header->type = IGMP_HEADER_TYPE_LEAVE_GROUP; /* Type.*/ 
        igmp_header->max_resp_time = 0;             /* Unused field, zeroed when sent, ignored when received.*/
        igmp_header->group_addr = group_addr ;      /* Group address field.*/   
        
        
        igmp_header->checksum = 0;
        igmp_header->checksum = fnet_checksum(nb_header, (int)nb_header->total_length);

        /* RFC 1112: A Report is sent with an IP destination address equal to the
         * host group address being reported, and with an IP time-to-live of 1.
         */
        
        fnet_ip_output(netif, INADDR_ANY, dest_ip /*dest_addr*/, FNET_IP_PROTOCOL_IGMP, FNET_IGMP_TOS, FNET_IGMP_TTL, nb_header, 0, 0, 0);
    }
#endif /* FNET_CFG_IGMP_VERSION */
}
/************************************************************************
* NAME: fnet_netif_init
*
* DESCRIPTION: This function installs & inits a network interface.
*************************************************************************/
int fnet_netif_init( fnet_netif_t *netif, unsigned char *hw_addr, unsigned int hw_addr_size )
{
    int result = FNET_OK;
    
    if(netif && netif->api)
    {
        fnet_os_mutex_lock();   
        
        fnet_isr_lock();
        
        netif->next = fnet_netif_list;

        if(netif->next != 0)
            netif->next->prev = netif;

        netif->prev = 0;
        fnet_netif_list = netif;
        
        fnet_netif_assign_scope_id( netif ); /* Asign Scope ID.*/
        
        netif->features = FNET_NETIF_FEATURE_NONE;


        /* Interface HW initialization.*/
        if(netif->api->init && ((result = netif->api->init(netif)) == FNET_OK))
        {
            #if FNET_CFG_IGMP && FNET_CFG_IP4       
                /**************************************************************
                 * RFC1112 7.2
                 *   To support IGMP, every level 2 host must
                 *   join the "all-hosts" group (address 224.0.0.1) on each network
                 *   interface at initialization time and must remain a member for as long
                 *   as the host is active.
                 *
                 * NOTE:(224.0.0.1) membership is never reported by IGMP.
                 **************************************************************/
                 /* Join HW interface. */
                fnet_netif_join_ip4_multicast ( netif, FNET_IP4_ADDR_INIT(224, 0, 0, 1) );
            #endif  /* FNET_CFG_IGMP */
            
            /* Set HW Address.*/    
            fnet_netif_set_hw_addr(netif, hw_addr, hw_addr_size);
                
            /* Interface-Type specific initialisation. */ 
            switch(netif->api->type)
            {
            #if (FNET_CFG_CPU_ETH0 ||FNET_CFG_CPU_ETH1)
                case (FNET_NETIF_TYPE_ETHERNET):
                    result = fnet_eth_init(netif);
                    break;
            #endif /* FNET_CFG_ETH */
                default:
                    break;
            
            }
        }

        fnet_printf("ETH - Initialization: %s, ID:%d\n", netif->name, netif->scope_id);
        fnet_printf("	 - IP: %x, GW: %x\n", netif->ip4_addr.address, netif->ip4_addr.gateway);
        fnet_printf("	 - MASK: %x, DHCP?: %d\n", netif->ip4_addr.netmask, netif->ip4_addr.is_automatic);
        fnet_printf("	 - MTU: %d\n", netif->mtu);
        fnet_printf("	 - MTU: %x\n", netif->if_ptr);



        fnet_isr_unlock();
        
        fnet_os_mutex_unlock();
    }
    
    return result;
}