Blame src/unix/ibmi.c

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