/*		
 * Copyright 2001 Mike McCormack
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"

#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

#include "winbase.h"
#include "winreg.h"
#include "wingdi.h"
#include "winuser.h"
#include "wine/debug.h"
#include "winerror.h"
#include "nb30.h"

#ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
#endif
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_SOCKET_H
# include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
#endif
#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
#endif

#ifdef HAVE_SOCKADDR_SA_LEN
#  ifndef max
#   define max(a,b) ((a) > (b) ? (a) : (b))
#  endif
#  define ifreq_size(i) max(sizeof(struct ifreq),\
sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
# else
#  define ifreq_size(i) sizeof(struct ifreq)
# endif /* defined(HAVE_SOCKADDR_SA_LEN) */

WINE_DEFAULT_DEBUG_CHANNEL(netbios);

HMODULE NETAPI32_hModule = 0;

struct NetBiosAdapter
{
    int valid;
    unsigned char address[6];
};

static struct NetBiosAdapter NETBIOS_Adapter[MAX_LANA];

# ifdef SIOCGIFHWADDR
int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
{
    if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0)
        return -1;
    memcpy(address, (unsigned char *)&ifr->ifr_hwaddr.sa_data, 6);
    return 0;
}
# else
#  ifdef SIOCGENADDR
int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
{
    if (ioctl(sd, SIOCGENADDR, ifr) < 0)
        return -1;
    memcpy(address, (unsigned char *) ifr->ifr_enaddr, 6);
    return 0;
}
#   else
int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
{
    return -1;
}
#  endif /* SIOCGENADDR */
# endif /* SIOCGIFHWADDR */

static UCHAR NETBIOS_Enum(PNCB ncb)
{
#ifdef HAVE_NET_IF_H
    int             sd;
    struct ifreq    ifr, *ifrp;
    struct ifconf   ifc;
    unsigned char   buf[1024];
    int             i, ofs;
#endif
    LANA_ENUM *lanas = (PLANA_ENUM) ncb->ncb_buffer;

    TRACE("NCBENUM\n");

    lanas->length = 0;

#ifdef HAVE_NET_IF_H
    /* BSD 4.4 defines the size of an ifreq to be
     * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
     * However, under earlier systems, sa_len isn't present, so
     *  the size is just sizeof(struct ifreq)
     */

    sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (sd < 0)
        return NRC_OPENERROR;

    memset(buf, 0, sizeof(buf));
    ifc.ifc_len = sizeof(buf);
    ifc.ifc_buf = buf;
    /* get the ifconf interface */
    if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)
    {
        close(sd);
        return NRC_OPENERROR;
    }

    /* loop through the interfaces, looking for a valid one */
    /* n = ifc.ifc_len; */
    ofs = 0;
    for (i = 0; i < ifc.ifc_len; i++)
    {
        unsigned char *a = NETBIOS_Adapter[i].address;

        ifrp = (struct ifreq *)((char *)ifc.ifc_buf+ofs);
        strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);

        /* try to get the address for this interface */
        if(get_hw_address(sd, &ifr, a)==0)
        {
            /* make sure it's not blank */
            /* if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
	        continue; */

            TRACE("Found valid adapter %d at %02x:%02x:%02x:%02x:%02x:%02x\n", i,
                        a[0],a[1],a[2],a[3],a[4],a[5]);

            NETBIOS_Adapter[i].valid = TRUE;
            lanas->lana[lanas->length] = i;
            lanas->length++;
        }
        ofs += ifreq_size(ifr);
    }
    close(sd);
#endif /* HAVE_NET_IF_H */
    return NRC_GOODRET;
}


static UCHAR NETBIOS_Astat(PNCB ncb)
{
    struct NetBiosAdapter *nad = &NETBIOS_Adapter[ncb->ncb_lana_num];
    PADAPTER_STATUS astat = (PADAPTER_STATUS) ncb->ncb_buffer;

    TRACE("NCBASTAT (Adapter %d)\n", ncb->ncb_lana_num);

    if(!nad->valid)
        return NRC_INVADDRESS;

    memset(astat, 0, sizeof astat);
    memcpy(astat->adapter_address, nad->address, sizeof astat->adapter_address);

    return NRC_GOODRET;
}

BOOL WINAPI
NETAPI32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);

    switch (fdwReason) {
	case DLL_PROCESS_ATTACH:
            NETAPI32_hModule = hinstDLL;
	    break;
	case DLL_PROCESS_DETACH:
	    break;
    }

    return TRUE;
}

BOOL WINAPI Netbios(PNCB pncb)
{
    UCHAR ret = NRC_ILLCMD; 

    TRACE("ncb = %p\n",pncb);

    if(!pncb)
        return NRC_INVADDRESS;

    switch(pncb->ncb_command&0x7f)
    {
    case NCBRESET:
        FIXME("NCBRESET adapter %d\n",pncb->ncb_lana_num);
        if( (pncb->ncb_lana_num < MAX_LANA ) && 
             NETBIOS_Adapter[pncb->ncb_lana_num].valid)
            ret = NRC_GOODRET;
        else
            ret = NRC_ILLCMD; /* NetBIOS emulator not found */
        break;

    case NCBADDNAME:
        FIXME("NCBADDNAME\n");
        break;

    case NCBADDGRNAME:
        FIXME("NCBADDGRNAME\n");
        break;

    case NCBDELNAME:
        FIXME("NCBDELNAME\n");
        break;

    case NCBSEND:
        FIXME("NCBSEND\n");
        break;

    case NCBRECV:
        FIXME("NCBRECV\n");
        break;

    case NCBHANGUP:
        FIXME("NCBHANGUP\n");
        break;

    case NCBCANCEL:
        FIXME("NCBCANCEL\n");
        break;

    case NCBLISTEN:
        FIXME("NCBLISTEN\n");
        break;

    case NCBASTAT:
        ret = NETBIOS_Astat(pncb);
        break;

    case NCBENUM:
        ret = NETBIOS_Enum(pncb);
        break;

    default:
        FIXME("(%p): command code %02x\n", pncb, pncb->ncb_command);

        ret = NRC_ILLCMD; /* NetBIOS emulator not found */
    }
    pncb->ncb_retcode = ret;
    return ret;
}

