/*
 * 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;
}

