/*
 * IP configuration utility
 *
 * Copyright 2008 Andrew Riedi
 * Copyright 2010 Andrew Nguyen
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <winsock2.h>
#include <windows.h>
#include <iphlpapi.h>
#include <wine/unicode.h>

#include "ipconfig.h"

static int ipconfig_vprintfW(const WCHAR *msg, __ms_va_list va_args)
{
    int wlen;
    DWORD count, ret;
    WCHAR msg_buffer[8192];

    wlen = FormatMessageW(FORMAT_MESSAGE_FROM_STRING, msg, 0, 0, msg_buffer,
                          sizeof(msg_buffer)/sizeof(*msg_buffer), &va_args);

    ret = WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), msg_buffer, wlen, &count, NULL);
    if (!ret)
    {
        DWORD len;
        char *msgA;

        /* On Windows WriteConsoleW() fails if the output is redirected. So fall
         * back to WriteFile(), assuming the console encoding is still the right
         * one in that case.
         */
        len = WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen,
            NULL, 0, NULL, NULL);
        msgA = HeapAlloc(GetProcessHeap(), 0, len);
        if (!msgA)
            return 0;

        WideCharToMultiByte(GetConsoleOutputCP(), 0, msg_buffer, wlen, msgA, len,
            NULL, NULL);
        WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), msgA, len, &count, FALSE);
        HeapFree(GetProcessHeap(), 0, msgA);
    }

    return count;
}

static int CDECL ipconfig_printfW(const WCHAR *msg, ...)
{
    __ms_va_list va_args;
    int len;

    __ms_va_start(va_args, msg);
    len = ipconfig_vprintfW(msg, va_args);
    __ms_va_end(va_args);

    return len;
}

static int CDECL ipconfig_message_printfW(int msg, ...)
{
    __ms_va_list va_args;
    WCHAR msg_buffer[8192];
    int len;

    LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
        sizeof(msg_buffer)/sizeof(WCHAR));

    __ms_va_start(va_args, msg);
    len = ipconfig_vprintfW(msg_buffer, va_args);
    __ms_va_end(va_args);

    return len;
}

static int ipconfig_message(int msg)
{
    static const WCHAR formatW[] = {'%','1',0};
    WCHAR msg_buffer[8192];

    LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
        sizeof(msg_buffer)/sizeof(WCHAR));

    return ipconfig_printfW(formatW, msg_buffer);
}

static const WCHAR *iftype_to_string(DWORD type)
{
    static WCHAR msg_buffer[50];

    int msg;

    switch (type)
    {
    case IF_TYPE_ETHERNET_CSMACD:
    /* The loopback adapter appears as an Ethernet device. */
    case IF_TYPE_SOFTWARE_LOOPBACK:
        msg = STRING_ETHERNET;
        break;
    default:
        msg = STRING_UNKNOWN;
    }

    LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
        sizeof(msg_buffer)/sizeof(WCHAR));

    return msg_buffer;
}

static void print_field(int msg, const WCHAR *value)
{
    static const WCHAR formatW[] = {' ',' ',' ',' ','%','1',':',' ','%','2','\n',0};

    WCHAR field[] = {'.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',
                     ' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ','.',' ',0};
    WCHAR name_buffer[sizeof(field)/sizeof(WCHAR)];

    LoadStringW(GetModuleHandleW(NULL), msg, name_buffer, sizeof(name_buffer)/sizeof(WCHAR));
    memcpy(field, name_buffer, sizeof(WCHAR) * min(strlenW(name_buffer), sizeof(field)/sizeof(WCHAR) - 1));

    ipconfig_printfW(formatW, field, value);
}

static void print_value(const WCHAR *value)
{
    static const WCHAR formatW[] = {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
                                    ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
                                    ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
                                    ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',
                                    '%','1','\n',0};

    ipconfig_printfW(formatW, value);
}

static BOOL socket_address_to_string(WCHAR *buf, DWORD len, SOCKET_ADDRESS *addr)
{
    return WSAAddressToStringW(addr->lpSockaddr,
                               addr->iSockaddrLength, NULL,
                               buf, &len) == 0;
}

static void print_basic_information(void)
{
    IP_ADAPTER_ADDRESSES *adapters;
    ULONG out = 0;

    if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
                             NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
    {
        adapters = HeapAlloc(GetProcessHeap(), 0, out);
        if (!adapters)
            exit(1);

        if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
                                 NULL, adapters, &out) == ERROR_SUCCESS)
        {
            IP_ADAPTER_ADDRESSES *p;

            for (p = adapters; p; p = p->Next)
            {
                static const WCHAR newlineW[] = {'\n',0};
                static const WCHAR emptyW[] = {0};

                IP_ADAPTER_UNICAST_ADDRESS *addr;
                IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
                WCHAR addr_buf[54];

                ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
                ipconfig_printfW(newlineW);
                print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);

                for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
                {
                    if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
                        print_field(STRING_IP_ADDRESS, addr_buf);
                    /* FIXME: Output corresponding subnet mask. */
                }

                if (p->FirstGatewayAddress)
                {
                    if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
                        print_field(STRING_DEFAULT_GATEWAY, addr_buf);

                    for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
                    {
                        if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
                            print_value(addr_buf);
                    }
                }
                else
                    print_field(STRING_DEFAULT_GATEWAY, emptyW);

                ipconfig_printfW(newlineW);
            }
        }

        HeapFree(GetProcessHeap(), 0, adapters);
    }
}

static const WCHAR *nodetype_to_string(DWORD type)
{
    static WCHAR msg_buffer[50];

    int msg;

    switch (type)
    {
    case BROADCAST_NODETYPE:
        msg = STRING_BROADCAST;
        break;
    case PEER_TO_PEER_NODETYPE:
        msg = STRING_PEER_TO_PEER;
        break;
    case MIXED_NODETYPE:
        msg = STRING_MIXED;
        break;
    case HYBRID_NODETYPE:
        msg = STRING_HYBRID;
        break;
    default:
        msg = STRING_UNKNOWN;
    }

    LoadStringW(GetModuleHandleW(NULL), msg, msg_buffer,
        sizeof(msg_buffer)/sizeof(WCHAR));

    return msg_buffer;
}

static WCHAR *physaddr_to_string(WCHAR *buf, BYTE *addr, DWORD len)
{
    static const WCHAR fmtW[] = {'%','0','2','X','-',0};
    static const WCHAR fmt2W[] = {'%','0','2','X',0};

    if (!len)
        *buf = '\0';
    else
    {
        WCHAR *p = buf;
        DWORD i;

        for (i = 0; i < len - 1; i++)
        {
            sprintfW(p, fmtW, addr[i]);
            p += 3;
        }
        sprintfW(p, fmt2W, addr[i]);
    }

    return buf;
}

static const WCHAR *boolean_to_string(int value)
{
    static WCHAR msg_buffer[15];

    LoadStringW(GetModuleHandleW(NULL), value ? STRING_YES : STRING_NO,
        msg_buffer, sizeof(msg_buffer)/sizeof(WCHAR));

    return msg_buffer;
}

static void print_full_information(void)
{
    static const WCHAR newlineW[] = {'\n',0};
    static const WCHAR emptyW[] = {0};

    FIXED_INFO *info;
    IP_ADAPTER_ADDRESSES *adapters;
    ULONG out = 0;

    if (GetNetworkParams(NULL, &out) == ERROR_BUFFER_OVERFLOW)
    {
        info = HeapAlloc(GetProcessHeap(), 0, out);
        if (!info)
            exit(1);

        if (GetNetworkParams(info, &out) == ERROR_SUCCESS)
        {
            WCHAR hostnameW[MAX_HOSTNAME_LEN + 4];

            MultiByteToWideChar(CP_ACP, 0, info->HostName, -1, hostnameW, sizeof(hostnameW)/sizeof(hostnameW[0]));
            print_field(STRING_HOSTNAME, hostnameW);

            /* FIXME: Output primary DNS suffix. */

            print_field(STRING_NODE_TYPE, nodetype_to_string(info->NodeType));
            print_field(STRING_IP_ROUTING, boolean_to_string(info->EnableRouting));

            /* FIXME: Output WINS proxy status and DNS suffix search list. */

            ipconfig_printfW(newlineW);
        }

        HeapFree(GetProcessHeap(), 0, info);
    }

    if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
                             NULL, NULL, &out) == ERROR_BUFFER_OVERFLOW)
    {
        adapters = HeapAlloc(GetProcessHeap(), 0, out);
        if (!adapters)
            exit(1);

        if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_ALL_GATEWAYS,
                                 NULL, adapters, &out) == ERROR_SUCCESS)
        {
            IP_ADAPTER_ADDRESSES *p;

            for (p = adapters; p; p = p->Next)
            {
                IP_ADAPTER_UNICAST_ADDRESS *addr;
                WCHAR physaddr_buf[3 * MAX_ADAPTER_ADDRESS_LENGTH];
                IP_ADAPTER_GATEWAY_ADDRESS_LH *gateway;
                WCHAR addr_buf[54];

                ipconfig_message_printfW(STRING_ADAPTER_FRIENDLY, iftype_to_string(p->IfType), p->FriendlyName);
                ipconfig_printfW(newlineW);
                print_field(STRING_CONN_DNS_SUFFIX, p->DnsSuffix);
                print_field(STRING_DESCRIPTION, p->Description);
                print_field(STRING_PHYS_ADDR, physaddr_to_string(physaddr_buf, p->PhysicalAddress, p->PhysicalAddressLength));
                print_field(STRING_DHCP_ENABLED, boolean_to_string(p->Flags & IP_ADAPTER_DHCP_ENABLED));

                /* FIXME: Output autoconfiguration status. */

                for (addr = p->FirstUnicastAddress; addr; addr = addr->Next)
                {
                    if (addr->Address.lpSockaddr->sa_family == AF_INET &&
                        socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
                        print_field(STRING_IP_ADDRESS, addr_buf);
                    else if (addr->Address.lpSockaddr->sa_family == AF_INET6 &&
                             socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &addr->Address))
                        print_field(STRING_IP6_ADDRESS, addr_buf);
                    /* FIXME: Output corresponding subnet mask. */
                }

                if (p->FirstGatewayAddress)
                {
                    if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &p->FirstGatewayAddress->Address))
                        print_field(STRING_DEFAULT_GATEWAY, addr_buf);

                    for (gateway = p->FirstGatewayAddress->Next; gateway; gateway = gateway->Next)
                    {
                        if (socket_address_to_string(addr_buf, sizeof(addr_buf)/sizeof(WCHAR), &gateway->Address))
                            print_value(addr_buf);
                    }
                }
                else
                    print_field(STRING_DEFAULT_GATEWAY, emptyW);

                ipconfig_printfW(newlineW);
            }
        }

        HeapFree(GetProcessHeap(), 0, adapters);
    }
}

int wmain(int argc, WCHAR *argv[])
{
    static const WCHAR slashHelp[] = {'/','?',0};
    static const WCHAR slashAll[] = {'/','a','l','l',0};

    WSADATA data;

    if (WSAStartup(MAKEWORD(2, 2), &data))
        return 1;

    if (argc > 1)
    {
        if (!strcmpW(slashHelp, argv[1]))
        {
            ipconfig_message(STRING_USAGE);
            WSACleanup();
            return 1;
        }
        else if (!strcmpiW(slashAll, argv[1]))
        {
            if (argv[2])
            {
                ipconfig_message(STRING_INVALID_CMDLINE);
                ipconfig_message(STRING_USAGE);
                WSACleanup();
                return 1;
            }

            print_full_information();
        }
        else
        {
            ipconfig_message(STRING_INVALID_CMDLINE);
            ipconfig_message(STRING_USAGE);
            WSACleanup();
            return 1;
        }
    }
    else
        print_basic_information();

    WSACleanup();
    return 0;
}
