Blame src/unix/ibmi.c

Packit b5b901
/* Copyright libuv project contributors. All rights reserved.
Packit b5b901
 *
Packit b5b901
 * Permission is hereby granted, free of charge, to any person obtaining a copy
Packit b5b901
 * of this software and associated documentation files (the "Software"), to
Packit b5b901
 * deal in the Software without restriction, including without limitation the
Packit b5b901
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
Packit b5b901
 * sell copies of the Software, and to permit persons to whom the Software is
Packit b5b901
 * furnished to do so, subject to the following conditions:
Packit b5b901
 *
Packit b5b901
 * The above copyright notice and this permission notice shall be included in
Packit b5b901
 * all copies or substantial portions of the Software.
Packit b5b901
 *
Packit b5b901
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit b5b901
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit b5b901
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Packit b5b901
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Packit b5b901
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Packit b5b901
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
Packit b5b901
 * IN THE SOFTWARE.
Packit b5b901
 */
Packit b5b901
Packit b5b901
#include "uv.h"
Packit b5b901
#include "internal.h"
Packit b5b901
Packit b5b901
#include <stdio.h>
Packit b5b901
#include <stdint.h>
Packit b5b901
#include <stdlib.h>
Packit b5b901
#include <string.h>
Packit b5b901
#include <assert.h>
Packit b5b901
#include <errno.h>
Packit b5b901
Packit b5b901
#include <sys/types.h>
Packit b5b901
#include <sys/socket.h>
Packit b5b901
#include <sys/ioctl.h>
Packit b5b901
#include <net/if.h>
Packit b5b901
#include <netinet/in.h>
Packit b5b901
#include <arpa/inet.h>
Packit b5b901
Packit b5b901
#include <sys/time.h>
Packit b5b901
#include <unistd.h>
Packit b5b901
#include <fcntl.h>
Packit b5b901
#include <utmp.h>
Packit b5b901
#include <libgen.h>
Packit b5b901
Packit b5b901
#include <sys/protosw.h>
Packit b5b901
#include <procinfo.h>
Packit b5b901
#include <sys/proc.h>
Packit b5b901
#include <sys/procfs.h>
Packit b5b901
Packit b5b901
#include <ctype.h>
Packit b5b901
Packit b5b901
#include <sys/mntctl.h>
Packit b5b901
#include <sys/vmount.h>
Packit b5b901
#include <limits.h>
Packit b5b901
#include <strings.h>
Packit b5b901
#include <sys/vnode.h>
Packit b5b901
Packit Service e08953
#include <as400_protos.h>
Packit Service e08953
#include <as400_types.h>
Packit Service e08953
Packit Service e08953
Packit Service e08953
typedef struct {
Packit Service e08953
  int bytes_available;
Packit Service e08953
  int bytes_returned;
Packit Service e08953
  char current_date_and_time[8];
Packit Service e08953
  char system_name[8];
Packit Service e08953
  char elapsed_time[6];
Packit Service e08953
  char restricted_state_flag;
Packit Service e08953
  char reserved;
Packit Service e08953
  int percent_processing_unit_used;
Packit Service e08953
  int jobs_in_system;
Packit Service e08953
  int percent_permanent_addresses;
Packit Service e08953
  int percent_temporary_addresses;
Packit Service e08953
  int system_asp;
Packit Service e08953
  int percent_system_asp_used;
Packit Service e08953
  int total_auxiliary_storage;
Packit Service e08953
  int current_unprotected_storage_used;
Packit Service e08953
  int maximum_unprotected_storage_used;
Packit Service e08953
  int percent_db_capability;
Packit Service e08953
  int main_storage_size;
Packit Service e08953
  int number_of_partitions;
Packit Service e08953
  int partition_identifier;
Packit Service e08953
  int reserved1;
Packit Service e08953
  int current_processing_capacity;
Packit Service e08953
  char processor_sharing_attribute;
Packit Service e08953
  char reserved2[3];
Packit Service e08953
  int number_of_processors;
Packit Service e08953
  int active_jobs_in_system;
Packit Service e08953
  int active_threads_in_system;
Packit Service e08953
  int maximum_jobs_in_system;
Packit Service e08953
  int percent_temporary_256mb_segments_used;
Packit Service e08953
  int percent_temporary_4gb_segments_used;
Packit Service e08953
  int percent_permanent_256mb_segments_used;
Packit Service e08953
  int percent_permanent_4gb_segments_used;
Packit Service e08953
  int percent_current_interactive_performance;
Packit Service e08953
  int percent_uncapped_cpu_capacity_used;
Packit Service e08953
  int percent_shared_processor_pool_used;
Packit Service e08953
  long main_storage_size_long;
Packit Service e08953
} SSTS0200;
Packit Service e08953
Packit Service e08953
Packit Service e08953
typedef struct {
Packit Service e08953
  char header[208];
Packit Service e08953
  unsigned char loca_adapter_address[12];
Packit Service e08953
} LIND0500;
Packit Service e08953
Packit Service e08953
Packit Service e08953
typedef struct {
Packit Service e08953
  int bytes_provided;
Packit Service e08953
  int bytes_available;
Packit Service e08953
  char msgid[7];
Packit Service e08953
} errcode_s;
Packit Service e08953
Packit Service e08953
Packit Service e08953
static const unsigned char e2a[256] = {
Packit Service e08953
    0, 1, 2, 3, 156, 9, 134, 127, 151, 141, 142, 11, 12, 13, 14, 15,
Packit Service e08953
    16, 17, 18, 19, 157, 133, 8, 135, 24, 25, 146, 143, 28, 29, 30, 31,
Packit Service e08953
    128, 129, 130, 131, 132, 10, 23, 27, 136, 137, 138, 139, 140, 5, 6, 7,
Packit Service e08953
    144, 145, 22, 147, 148, 149, 150, 4, 152, 153, 154, 155, 20, 21, 158, 26,
Packit Service e08953
    32, 160, 161, 162, 163, 164, 165, 166, 167, 168, 91, 46, 60, 40, 43, 33,
Packit Service e08953
    38, 169, 170, 171, 172, 173, 174, 175, 176, 177, 93, 36, 42, 41, 59, 94,
Packit Service e08953
    45, 47, 178, 179, 180, 181, 182, 183, 184, 185, 124, 44, 37, 95, 62, 63,
Packit Service e08953
    186, 187, 188, 189, 190, 191, 192, 193, 194, 96, 58, 35, 64, 39, 61, 34,
Packit Service e08953
    195, 97, 98, 99, 100, 101, 102, 103, 104, 105, 196, 197, 198, 199, 200, 201,
Packit Service e08953
    202, 106, 107, 108, 109, 110, 111, 112, 113, 114, 203, 204, 205, 206, 207, 208,
Packit Service e08953
    209, 126, 115, 116, 117, 118, 119, 120, 121, 122, 210, 211, 212, 213, 214, 215,
Packit Service e08953
    216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231,
Packit Service e08953
    123, 65, 66, 67, 68, 69, 70, 71, 72, 73, 232, 233, 234, 235, 236, 237,
Packit Service e08953
    125, 74, 75, 76, 77, 78, 79, 80, 81, 82, 238, 239, 240, 241, 242, 243,
Packit Service e08953
    92, 159, 83, 84, 85, 86, 87, 88, 89, 90, 244, 245, 246, 247, 248, 249,
Packit Service e08953
    48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 250, 251, 252, 253, 254, 255};
Packit Service e08953
Packit Service e08953
Packit Service e08953
static const unsigned char a2e[256] = {
Packit Service e08953
    0, 1, 2, 3, 55, 45, 46, 47, 22, 5, 37, 11, 12, 13, 14, 15,
Packit Service e08953
    16, 17, 18, 19, 60, 61, 50, 38, 24, 25, 63, 39, 28, 29, 30, 31,
Packit Service e08953
    64, 79, 127, 123, 91, 108, 80, 125, 77, 93, 92, 78, 107, 96, 75, 97,
Packit Service e08953
    240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 122, 94, 76, 126, 110, 111,
Packit Service e08953
    124, 193, 194, 195, 196, 197, 198, 199, 200, 201, 209, 210, 211, 212, 213, 214,
Packit Service e08953
    215, 216, 217, 226, 227, 228, 229, 230, 231, 232, 233, 74, 224, 90, 95, 109,
Packit Service e08953
    121, 129, 130, 131, 132, 133, 134, 135, 136, 137, 145, 146, 147, 148, 149, 150,
Packit Service e08953
    151, 152, 153, 162, 163, 164, 165, 166, 167, 168, 169, 192, 106, 208, 161, 7,
Packit Service e08953
    32, 33, 34, 35, 36, 21, 6, 23, 40, 41, 42, 43, 44, 9, 10, 27,
Packit Service e08953
    48, 49, 26, 51, 52, 53, 54, 8, 56, 57, 58, 59, 4, 20, 62, 225,
Packit Service e08953
    65, 66, 67, 68, 69, 70, 71, 72, 73, 81, 82, 83, 84, 85, 86, 87,
Packit Service e08953
    88, 89, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116, 117,
Packit Service e08953
    118, 119, 120, 128, 138, 139, 140, 141, 142, 143, 144, 154, 155, 156, 157, 158,
Packit Service e08953
    159, 160, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183,
Packit Service e08953
    184, 185, 186, 187, 188, 189, 190, 191, 202, 203, 204, 205, 206, 207, 218, 219,
Packit Service e08953
    220, 221, 222, 223, 234, 235, 236, 237, 238, 239, 250, 251, 252, 253, 254, 255};
Packit Service e08953
Packit Service e08953
Packit Service e08953
static void iconv_e2a(unsigned char src[], unsigned char dst[], size_t length) {
Packit Service e08953
  size_t i;
Packit Service e08953
  for (i = 0; i < length; i++)
Packit Service e08953
    dst[i] = e2a[src[i]];
Packit Service e08953
}
Packit Service e08953
Packit Service e08953
Packit Service e08953
static void iconv_a2e(const char* src, unsigned char dst[], size_t length) {
Packit Service e08953
  size_t srclen;
Packit Service e08953
  size_t i;
Packit Service e08953
Packit Service e08953
  srclen = strlen(src);
Packit Service e08953
  if (srclen > length)
Packit Service e08953
    abort();
Packit Service e08953
  for (i = 0; i < srclen; i++)
Packit Service e08953
    dst[i] = a2e[src[i]];
Packit Service e08953
  /* padding the remaining part with spaces */
Packit Service e08953
  for (; i < length; i++)
Packit Service e08953
    dst[i] = a2e[' '];
Packit Service e08953
}
Packit Service e08953
Packit Service e08953
Packit Service e08953
static int get_ibmi_system_status(SSTS0200* rcvr) {
Packit Service e08953
  /* rcvrlen is input parameter 2 to QWCRSSTS */
Packit Service e08953
  unsigned int rcvrlen = sizeof(*rcvr);
Packit Service e08953
  unsigned char format[8], reset_status[10];
Packit Service e08953
Packit Service e08953
  /* format is input parameter 3 to QWCRSSTS */
Packit Service e08953
  iconv_a2e("SSTS0200", format, sizeof(format));
Packit Service e08953
  /* reset_status is input parameter 4 */
Packit Service e08953
  iconv_a2e("*NO", reset_status, sizeof(reset_status));
Packit Service e08953
Packit Service e08953
  /* errcode is input parameter 5 to QWCRSSTS */
Packit Service e08953
  errcode_s errcode;
Packit Service e08953
Packit Service e08953
  /* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */
Packit Service e08953
  ILEpointer __attribute__((aligned(16))) qwcrssts_pointer;
Packit Service e08953
Packit Service e08953
  /* qwcrssts_argv is the array of argument pointers to QWCRSSTS */
Packit Service e08953
  void* qwcrssts_argv[6];
Packit Service e08953
Packit Service e08953
  /* Set the IBM i pointer to the QSYS/QWCRSSTS *PGM object */
Packit Service e08953
  int rc = _RSLOBJ2(&qwcrssts_pointer, RSLOBJ_TS_PGM, "QWCRSSTS", "QSYS");
Packit Service e08953
Packit Service e08953
  if (rc != 0)
Packit Service e08953
    return rc;
Packit Service e08953
Packit Service e08953
  /* initialize the QWCRSSTS returned info structure */
Packit Service e08953
  memset(rcvr, 0, sizeof(*rcvr));
Packit Service e08953
Packit Service e08953
  /* initialize the QWCRSSTS error code structure */
Packit Service e08953
  memset(&errcode, 0, sizeof(errcode));
Packit Service e08953
  errcode.bytes_provided = sizeof(errcode);
Packit Service e08953
Packit Service e08953
  /* initialize the array of argument pointers for the QWCRSSTS API */
Packit Service e08953
  qwcrssts_argv[0] = rcvr;
Packit Service e08953
  qwcrssts_argv[1] = &rcvrlen;
Packit Service e08953
  qwcrssts_argv[2] = &format;
Packit Service e08953
  qwcrssts_argv[3] = &reset_status;
Packit Service e08953
  qwcrssts_argv[4] = &errcode;
Packit Service e08953
  qwcrssts_argv[5] = NULL;
Packit Service e08953
Packit Service e08953
  /* Call the IBM i QWCRSSTS API from PASE */
Packit Service e08953
  rc = _PGMCALL(&qwcrssts_pointer, qwcrssts_argv, 0);
Packit Service e08953
Packit Service e08953
  return rc;
Packit Service e08953
}
Packit Service e08953
Packit Service e08953
Packit b5b901
uint64_t uv_get_free_memory(void) {
Packit Service e08953
  SSTS0200 rcvr;
Packit Service e08953
Packit Service e08953
  if (get_ibmi_system_status(&rcvr))
Packit Service e08953
    return 0;
Packit Service e08953
Packit Service e08953
  return (uint64_t)rcvr.main_storage_size * 1024ULL;
Packit b5b901
}
Packit b5b901
Packit b5b901
Packit b5b901
uint64_t uv_get_total_memory(void) {
Packit Service e08953
  SSTS0200 rcvr;
Packit Service e08953
Packit Service e08953
  if (get_ibmi_system_status(&rcvr))
Packit Service e08953
    return 0;
Packit Service e08953
Packit Service e08953
  return (uint64_t)rcvr.main_storage_size * 1024ULL;
Packit Service e08953
}
Packit Service e08953
Packit Service e08953
Packit Service e08953
uint64_t uv_get_constrained_memory(void) {
Packit Service e08953
  return 0;  /* Memory constraints are unknown. */
Packit b5b901
}
Packit b5b901
Packit b5b901
Packit b5b901
void uv_loadavg(double avg[3]) {
Packit Service e08953
  SSTS0200 rcvr;
Packit Service e08953
Packit Service e08953
  if (get_ibmi_system_status(&rcvr)) {
Packit b5b901
    avg[0] = avg[1] = avg[2] = 0;
Packit b5b901
    return;
Packit Service e08953
  }
Packit Service e08953
Packit Service e08953
  /* The average (in tenths) of the elapsed time during which the processing
Packit Service e08953
   * units were in use. For example, a value of 411 in binary would be 41.1%.
Packit Service e08953
   * This percentage could be greater than 100% for an uncapped partition.
Packit Service e08953
   */
Packit Service e08953
  double processing_unit_used_percent =
Packit Service e08953
    rcvr.percent_processing_unit_used / 1000.0;
Packit Service e08953
Packit Service e08953
  avg[0] = avg[1] = avg[2] = processing_unit_used_percent;
Packit b5b901
}
Packit b5b901
Packit b5b901
Packit b5b901
int uv_resident_set_memory(size_t* rss) {
Packit b5b901
  *rss = 0;
Packit b5b901
  return 0;
Packit b5b901
}
Packit b5b901
Packit b5b901
Packit b5b901
int uv_uptime(double* uptime) {
Packit b5b901
  return UV_ENOSYS;
Packit b5b901
}
Packit b5b901
Packit b5b901
Packit b5b901
int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
Packit b5b901
  unsigned int numcpus, idx = 0;
Packit b5b901
  uv_cpu_info_t* cpu_info;
Packit b5b901
Packit b5b901
  *cpu_infos = NULL;
Packit b5b901
  *count = 0;
Packit b5b901
Packit b5b901
  numcpus = sysconf(_SC_NPROCESSORS_ONLN);
Packit b5b901
Packit b5b901
  *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t));
Packit b5b901
  if (!*cpu_infos) {
Packit b5b901
    return UV_ENOMEM;
Packit b5b901
  }
Packit b5b901
Packit b5b901
  cpu_info = *cpu_infos;
Packit b5b901
  for (idx = 0; idx < numcpus; idx++) {
Packit b5b901
    cpu_info->speed = 0;
Packit b5b901
    cpu_info->model = uv__strdup("unknown");
Packit b5b901
    cpu_info->cpu_times.user = 0;
Packit b5b901
    cpu_info->cpu_times.sys = 0;
Packit b5b901
    cpu_info->cpu_times.idle = 0;
Packit b5b901
    cpu_info->cpu_times.irq = 0;
Packit b5b901
    cpu_info->cpu_times.nice = 0;
Packit b5b901
    cpu_info++;
Packit b5b901
  }
Packit b5b901
  *count = numcpus;
Packit b5b901
Packit b5b901
  return 0;
Packit Service e08953
}
Packit Service e08953
Packit Service e08953
Packit Service e08953
static int get_ibmi_physical_address(const char* line, char (*phys_addr)[6]) {
Packit Service e08953
  LIND0500 rcvr;
Packit Service e08953
  /* rcvrlen is input parameter 2 to QDCRLIND */
Packit Service e08953
  unsigned int rcvrlen = sizeof(rcvr);
Packit Service e08953
  unsigned char format[8], line_name[10];
Packit Service e08953
  unsigned char mac_addr[sizeof(rcvr.loca_adapter_address)];
Packit Service e08953
  int c[6];
Packit Service e08953
Packit Service e08953
  /* format is input parameter 3 to QDCRLIND */
Packit Service e08953
  iconv_a2e("LIND0500", format, sizeof(format));
Packit Service e08953
Packit Service e08953
  /* line_name is input parameter 4 to QDCRLIND */
Packit Service e08953
  iconv_a2e(line, line_name, sizeof(line_name));
Packit Service e08953
Packit Service e08953
  /* err is input parameter 5 to QDCRLIND */
Packit Service e08953
  errcode_s err;
Packit Service e08953
Packit Service e08953
  /* qwcrssts_pointer is the 16-byte tagged system pointer to QDCRLIND */
Packit Service e08953
  ILEpointer __attribute__((aligned(16))) qdcrlind_pointer;
Packit Service e08953
Packit Service e08953
  /* qwcrssts_argv is the array of argument pointers to QDCRLIND */
Packit Service e08953
  void* qdcrlind_argv[6];
Packit Service e08953
Packit Service e08953
  /* Set the IBM i pointer to the QSYS/QDCRLIND *PGM object */
Packit Service e08953
  int rc = _RSLOBJ2(&qdcrlind_pointer, RSLOBJ_TS_PGM, "QDCRLIND", "QSYS");
Packit Service e08953
Packit Service e08953
  if (rc != 0)
Packit Service e08953
    return rc;
Packit Service e08953
Packit Service e08953
  /* initialize the QDCRLIND returned info structure */
Packit Service e08953
  memset(&rcvr, 0, sizeof(rcvr));
Packit Service e08953
Packit Service e08953
  /* initialize the QDCRLIND error code structure */
Packit Service e08953
  memset(&err, 0, sizeof(err));
Packit Service e08953
  err.bytes_provided = sizeof(err);
Packit Service e08953
Packit Service e08953
  /* initialize the array of argument pointers for the QDCRLIND API */
Packit Service e08953
  qdcrlind_argv[0] = &rcv;;
Packit Service e08953
  qdcrlind_argv[1] = &rcvrlen;
Packit Service e08953
  qdcrlind_argv[2] = &format;
Packit Service e08953
  qdcrlind_argv[3] = &line_name;
Packit Service e08953
  qdcrlind_argv[4] = &err;
Packit Service e08953
  qdcrlind_argv[5] = NULL;
Packit Service e08953
Packit Service e08953
  /* Call the IBM i QDCRLIND API from PASE */
Packit Service e08953
  rc = _PGMCALL(&qdcrlind_pointer, qdcrlind_argv, 0);
Packit Service e08953
  if (rc != 0)
Packit Service e08953
    return rc;
Packit Service e08953
Packit Service e08953
  /* convert ebcdic loca_adapter_address to ascii first */
Packit Service e08953
  iconv_e2a(rcvr.loca_adapter_address, mac_addr,
Packit Service e08953
            sizeof(rcvr.loca_adapter_address));
Packit Service e08953
Packit Service e08953
  /* convert loca_adapter_address(char[12]) to phys_addr(char[6]) */
Packit Service e08953
  int r = sscanf(mac_addr, "%02x%02x%02x%02x%02x%02x",
Packit Service e08953
                &c[0], &c[1], &c[2], &c[3], &c[4], &c[5]);
Packit Service e08953
Packit Service e08953
  if (r == ARRAY_SIZE(c)) {
Packit Service e08953
    (*phys_addr)[0] = c[0];
Packit Service e08953
    (*phys_addr)[1] = c[1];
Packit Service e08953
    (*phys_addr)[2] = c[2];
Packit Service e08953
    (*phys_addr)[3] = c[3];
Packit Service e08953
    (*phys_addr)[4] = c[4];
Packit Service e08953
    (*phys_addr)[5] = c[5];
Packit Service e08953
  } else {
Packit Service e08953
    memset(*phys_addr, 0, sizeof(*phys_addr));
Packit Service e08953
    rc = -1;
Packit Service e08953
  }
Packit Service e08953
  return rc;
Packit Service e08953
}
Packit Service e08953
Packit Service e08953
Packit Service e08953
int uv_interface_addresses(uv_interface_address_t** addresses, int* count) {
Packit Service e08953
  uv_interface_address_t* address;
Packit Service e08953
  struct ifaddrs_pase *ifap = NULL, *cur;
Packit Service e08953
  int inet6, r = 0;
Packit Service e08953
Packit Service e08953
  *count = 0;
Packit Service e08953
  *addresses = NULL;
Packit Service e08953
Packit Service e08953
  if (Qp2getifaddrs(&ifap))
Packit Service e08953
    return UV_ENOSYS;
Packit Service e08953
Packit Service e08953
  /* The first loop to get the size of the array to be allocated */
Packit Service e08953
  for (cur = ifap; cur; cur = cur->ifa_next) {
Packit Service e08953
    if (!(cur->ifa_addr->sa_family == AF_INET6 ||
Packit Service e08953
          cur->ifa_addr->sa_family == AF_INET))
Packit Service e08953
      continue;
Packit Service e08953
Packit Service e08953
    if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
Packit Service e08953
      continue;
Packit Service e08953
Packit Service e08953
    (*count)++;
Packit Service e08953
  }
Packit Service e08953
Packit Service e08953
  if (*count == 0) {
Packit Service e08953
    Qp2freeifaddrs(ifap);
Packit Service e08953
    return 0;
Packit Service e08953
  }
Packit Service e08953
Packit Service e08953
  /* Alloc the return interface structs */
Packit Service e08953
  *addresses = uv__calloc(*count, sizeof(**addresses));
Packit Service e08953
  if (*addresses == NULL) {
Packit Service e08953
    Qp2freeifaddrs(ifap);
Packit Service e08953
    return UV_ENOMEM;
Packit Service e08953
  }
Packit Service e08953
  address = *addresses;
Packit Service e08953
Packit Service e08953
  /* The second loop to fill in the array */
Packit Service e08953
  for (cur = ifap; cur; cur = cur->ifa_next) {
Packit Service e08953
    if (!(cur->ifa_addr->sa_family == AF_INET6 ||
Packit Service e08953
          cur->ifa_addr->sa_family == AF_INET))
Packit Service e08953
      continue;
Packit Service e08953
Packit Service e08953
    if (!(cur->ifa_flags & IFF_UP && cur->ifa_flags & IFF_RUNNING))
Packit Service e08953
      continue;
Packit Service e08953
Packit Service e08953
    address->name = uv__strdup(cur->ifa_name);
Packit Service e08953
Packit Service e08953
    inet6 = (cur->ifa_addr->sa_family == AF_INET6);
Packit Service e08953
Packit Service e08953
    if (inet6) {
Packit Service e08953
      address->address.address6 = *((struct sockaddr_in6*)cur->ifa_addr);
Packit Service e08953
      address->netmask.netmask6 = *((struct sockaddr_in6*)cur->ifa_netmask);
Packit Service e08953
      address->netmask.netmask6.sin6_family = AF_INET6;
Packit Service e08953
    } else {
Packit Service e08953
      address->address.address4 = *((struct sockaddr_in*)cur->ifa_addr);
Packit Service e08953
      address->netmask.netmask4 = *((struct sockaddr_in*)cur->ifa_netmask);
Packit Service e08953
      address->netmask.netmask4.sin_family = AF_INET;
Packit Service e08953
    }
Packit Service e08953
    address->is_internal = cur->ifa_flags & IFF_LOOPBACK ? 1 : 0;
Packit Service e08953
    if (!address->is_internal) {
Packit Service e08953
      int rc = get_ibmi_physical_address(address->name, &address->phys_addr);
Packit Service e08953
      if (rc != 0)
Packit Service e08953
        r = rc;
Packit Service e08953
    }
Packit Service e08953
Packit Service e08953
    address++;
Packit Service e08953
  }
Packit Service e08953
Packit Service e08953
  Qp2freeifaddrs(ifap);
Packit Service e08953
  return r;
Packit Service e08953
}
Packit Service e08953
Packit Service e08953
Packit Service e08953
void uv_free_interface_addresses(uv_interface_address_t* addresses, int count) {
Packit Service e08953
  int i;
Packit Service e08953
Packit Service e08953
  for (i = 0; i < count; ++i) {
Packit Service e08953
    uv__free(addresses[i].name);
Packit Service e08953
  }
Packit Service e08953
Packit Service e08953
  uv__free(addresses);
Packit Service e08953
}