<commit_before>/***
  This file is part of catta.

  catta 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.

  catta 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 catta; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA.
***/

#include "iface-windows.h"
#include "iface.h"

#include <stdlib.h> // wcstombs
#include <catta/malloc.h>
#include <catta/log.h>
#include <iphlpapi.h>
#include "hashmap.h"
#include "util.h"   // catta_format_mac_address


// for the luid-to-idx hashmap
static unsigned luid_hash(const void *data)
{
    return ((NET_LUID *)data)->Info.NetLuidIndex;
}
static int luid_equal(const void *a, const void *b)
{
    return (((NET_LUID *)a)->Value == ((NET_LUID *)b)->Value);
}

static CattaIfIndex find_ifindex(CattaInterfaceMonitor *m, NET_LUID luid)
{
    CattaIfIndex *pi = NULL;
    NET_LUID *key = NULL;

    if((pi = catta_hashmap_lookup(m->osdep.idxmap, &luid)) == NULL) {
        // allocate memory for the hashmap key and value
        key = catta_malloc(sizeof(luid));
        pi = catta_malloc(sizeof(CattaIfIndex));
        if(!key || !pi)
            goto fail;

        *key = luid;
            
        // find an index for this luid
        *pi = m->osdep.nidx;
        if(*pi < 0)  // overflow
            goto fail;

        // register the index
        if(catta_hashmap_replace(m->osdep.idxmap, key, pi) < 0)
            goto fail;
        m->osdep.nidx++;
    }

    return *pi;

fail:
    catta_free(key);
    catta_free(pi);
    return -1;
}

// integrate the information from an IP_ADAPTER_ADDRESSES structure
// as returned by GetAdaptersAddresses into the CattaInterfaceMonitor
static void ip_adapter_address(CattaInterfaceMonitor *m, IP_ADAPTER_ADDRESSES *p)
{
    CattaIfIndex idx;
    CattaHwInterface *hw;
    size_t n;

    // look up the interface index by LUID
    if((idx = find_ifindex(m, p->Luid)) < 0) {
        catta_log_error("could not allocate index ip_adapter_address");
        return;
    }

    // find the CattaHwInterface by index or allocate a new one
    if((hw = catta_interface_monitor_get_hw_interface(m, idx)) == NULL) {
        if((hw = catta_hw_interface_new(m, idx)) == NULL) {
            catta_log_error("catta_hw_interface_new failed in ip_adapter_address");
            return;
        }
    }

    // fill the CattaHwInterface struct with data
    hw->flags_ok =
        (p->OperStatus & IfOperStatusUp) &&
        !(p->IfType & IF_TYPE_SOFTWARE_LOOPBACK) &&
        !(p->Flags & IP_ADAPTER_NO_MULTICAST) &&
        (m->server->config.allow_point_to_point || !(p->IfType & IF_TYPE_PPP));
            // XXX what about IF_TYPE_TUNNEL?

    n = wcstombs(NULL, p->FriendlyName, 0) + 1;
    catta_free(hw->name);
    hw->name = catta_new(char, n);
    wcstombs(hw->name, p->FriendlyName, n);

    hw->mtu = p->Mtu;

    hw->mac_address_size = p->PhysicalAddressLength;
    if(hw->mac_address_size > CATTA_MAC_ADDRESS_MAX)
        hw->mac_address_size = CATTA_MAC_ADDRESS_MAX;
    memcpy(hw->mac_address, p->PhysicalAddress, hw->mac_address_size);

    // XXX process addresses

    // XXX debugging, remove
   { 
     char mac[256]; 
     catta_log_debug("======\n name: %s\n index:%d\n mtu:%d\n mac:%s\n flags_ok:%d\n======",  
 		    hw->name, hw->index,  
 		    hw->mtu,  
 		    catta_format_mac_address(mac, sizeof(mac), hw->mac_address, hw->mac_address_size), 
 		    hw->flags_ok); <commit_msg>fix flags_ok computation (IfType and OperStatus are ordinals, not flags)<commit_after>/***
  This file is part of catta.

  catta 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.

  catta 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 catta; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  USA.
***/

#include "iface-windows.h"
#include "iface.h"

#include <stdlib.h> // wcstombs
#include <catta/malloc.h>
#include <catta/log.h>
#include <iphlpapi.h>
#include "hashmap.h"
#include "util.h"   // catta_format_mac_address


// for the luid-to-idx hashmap
static unsigned luid_hash(const void *data)
{
    return ((NET_LUID *)data)->Info.NetLuidIndex;
}
static int luid_equal(const void *a, const void *b)
{
    return (((NET_LUID *)a)->Value == ((NET_LUID *)b)->Value);
}

static CattaIfIndex find_ifindex(CattaInterfaceMonitor *m, NET_LUID luid)
{
    CattaIfIndex *pi = NULL;
    NET_LUID *key = NULL;

    if((pi = catta_hashmap_lookup(m->osdep.idxmap, &luid)) == NULL) {
        // allocate memory for the hashmap key and value
        key = catta_malloc(sizeof(luid));
        pi = catta_malloc(sizeof(CattaIfIndex));
        if(!key || !pi)
            goto fail;

        *key = luid;
            
        // find an index for this luid
        *pi = m->osdep.nidx;
        if(*pi < 0)  // overflow
            goto fail;

        // register the index
        if(catta_hashmap_replace(m->osdep.idxmap, key, pi) < 0)
            goto fail;
        m->osdep.nidx++;
    }

    return *pi;

fail:
    catta_free(key);
    catta_free(pi);
    return -1;
}

// integrate the information from an IP_ADAPTER_ADDRESSES structure
// as returned by GetAdaptersAddresses into the CattaInterfaceMonitor
static void ip_adapter_address(CattaInterfaceMonitor *m, IP_ADAPTER_ADDRESSES *p)
{
    CattaIfIndex idx;
    CattaHwInterface *hw;
    size_t n;

    // look up the interface index by LUID
    if((idx = find_ifindex(m, p->Luid)) < 0) {
        catta_log_error("could not allocate index ip_adapter_address");
        return;
    }

    // find the CattaHwInterface by index or allocate a new one
    if((hw = catta_interface_monitor_get_hw_interface(m, idx)) == NULL) {
        if((hw = catta_hw_interface_new(m, idx)) == NULL) {
            catta_log_error("catta_hw_interface_new failed in ip_adapter_address");
            return;
        }
    }

    // fill the CattaHwInterface struct with data
    hw->flags_ok =
        (p->OperStatus == IfOperStatusUp) &&
        !(p->IfType == IF_TYPE_SOFTWARE_LOOPBACK) &&
        !(p->Flags & IP_ADAPTER_NO_MULTICAST) &&
        (m->server->config.allow_point_to_point || !(p->IfType == IF_TYPE_PPP));
            // XXX what about IF_TYPE_TUNNEL?

    n = wcstombs(NULL, p->FriendlyName, 0) + 1;
    catta_free(hw->name);
    hw->name = catta_new(char, n);
    wcstombs(hw->name, p->FriendlyName, n);

    hw->mtu = p->Mtu;

    hw->mac_address_size = p->PhysicalAddressLength;
    if(hw->mac_address_size > CATTA_MAC_ADDRESS_MAX)
        hw->mac_address_size = CATTA_MAC_ADDRESS_MAX;
    memcpy(hw->mac_address, p->PhysicalAddress, hw->mac_address_size);

    // XXX process addresses

    // XXX debugging, remove
   { 
     char mac[256]; 
     catta_log_debug("======\n name: %s\n index:%d\n mtu:%d\n mac:%s\n type:%u\n status:%u\n multicast:%d\n flags:0x%.4x\n flags_ok:%d\n======",  
 		    hw->name, hw->index,  
 		    hw->mtu,  
 		    catta_format_mac_address(mac, sizeof(mac), hw->mac_address, hw->mac_address_size), 
 		    (unsigned int)p->IfType,
 		    (unsigned int)p->OperStatus,
 		    !(p->Flags & IP_ADAPTER_NO_MULTICAST),
 		    (unsigned int)p->Flags,
            hw->flags_ok); 
{'fraction_non_alphanumeric': 0.11794554455445544, 'fraction_numerical': 0.006435643564356435, 'mean_word_length': 2.924720738222438, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 87, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '468613', 'n_tokens_mistral': 2827, 'n_tokens_neox': 2703, 'n_words': 739}