1e472dc9dSDoug MacEachern/*
273f9b8cfSDoug MacEachern * Copyright (c) 2004-2009 Hyperic, Inc.
373f9b8cfSDoug MacEachern * Copyright (c) 2009 SpringSource, Inc.
473f9b8cfSDoug MacEachern * Copyright (c) 2009-2010 VMware, Inc.
573f9b8cfSDoug MacEachern *
673f9b8cfSDoug MacEachern * Licensed under the Apache License, Version 2.0 (the "License");
773f9b8cfSDoug MacEachern * you may not use this file except in compliance with the License.
873f9b8cfSDoug MacEachern * You may obtain a copy of the License at
973f9b8cfSDoug MacEachern *
1073f9b8cfSDoug MacEachern *     http://www.apache.org/licenses/LICENSE-2.0
1173f9b8cfSDoug MacEachern *
1273f9b8cfSDoug MacEachern * Unless required by applicable law or agreed to in writing, software
1373f9b8cfSDoug MacEachern * distributed under the License is distributed on an "AS IS" BASIS,
1473f9b8cfSDoug MacEachern * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1573f9b8cfSDoug MacEachern * See the License for the specific language governing permissions and
1673f9b8cfSDoug MacEachern * limitations under the License.
17e472dc9dSDoug MacEachern */
18e472dc9dSDoug MacEachern
19fa69ed85SDoug MacEachern/* pull in time.h before resource.h does w/ _KERNEL */
20fa69ed85SDoug MacEachern#include <sys/time.h>
21829a4c03STrond Norbye#define _KERNEL 1
22fa69ed85SDoug MacEachern#include <sys/file.h>     /* for struct file */
23fa69ed85SDoug MacEachern#include <sys/resource.h> /* for rlimit32 in 64-bit mode */
24730ee368SDoug MacEachern#undef  _KERNEL
25730ee368SDoug MacEachern
26dffe0da8SDoug MacEachern#include "sigar.h"
27dffe0da8SDoug MacEachern#include "sigar_private.h"
28dffe0da8SDoug MacEachern#include "sigar_util.h"
295630d9a4SDoug MacEachern#include "sigar_os.h"
30dffe0da8SDoug MacEachern
319a00bf0cSDoug MacEachern#include <dlfcn.h>
32dffe0da8SDoug MacEachern#include <nlist.h>
33bee745afSDoug MacEachern#include <pthread.h>
34dffe0da8SDoug MacEachern#include <stdio.h>
35dffe0da8SDoug MacEachern#include <utmp.h>
364c587388SDoug MacEachern#include <libperfstat.h>
374c587388SDoug MacEachern#include <pthread.h>
38dffe0da8SDoug MacEachern
39dffe0da8SDoug MacEachern#include <sys/statfs.h>
40dffe0da8SDoug MacEachern#include <sys/systemcfg.h>
41dffe0da8SDoug MacEachern#include <sys/sysinfo.h>
42dffe0da8SDoug MacEachern#include <sys/var.h>
43dffe0da8SDoug MacEachern#include <sys/vminfo.h>
44dffe0da8SDoug MacEachern#include <sys/mntctl.h>
45dffe0da8SDoug MacEachern#include <sys/stat.h>
46dffe0da8SDoug MacEachern#include <sys/user.h>
47471d4bb0SDoug MacEachern#include <sys/utsname.h>
48dffe0da8SDoug MacEachern#include <sys/vmount.h>
49c9266208SDoug MacEachern#include <sys/proc.h>
50dffe0da8SDoug MacEachern
51dffe0da8SDoug MacEachern#include <sys/socket.h>
52dffe0da8SDoug MacEachern#include <arpa/inet.h>
53dffe0da8SDoug MacEachern#include <net/if.h>
54dffe0da8SDoug MacEachern
55730ee368SDoug MacEachern/* for proc_port */
56730ee368SDoug MacEachern#include <netinet/in_pcb.h>
57730ee368SDoug MacEachern#include <sys/domain.h>
58730ee368SDoug MacEachern#include <sys/protosw.h>
59730ee368SDoug MacEachern#include <sys/socketvar.h>
60730ee368SDoug MacEachern
61b1815c1dSDoug MacEachern/* for net_connection_list */
62b1815c1dSDoug MacEachern#include <netinet/ip_var.h>
63b1815c1dSDoug MacEachern#include <netinet/tcp_timer.h>
64b1815c1dSDoug MacEachern#include <netinet/tcp_var.h>
65b1815c1dSDoug MacEachern#include <netinet/tcp_fsm.h>
66b1815c1dSDoug MacEachern
673575b131SDoug MacEachern/* for odm api */
683575b131SDoug MacEachern#include <sys/cfgodm.h>
693575b131SDoug MacEachern#include <sys/cfgdb.h>
703575b131SDoug MacEachern#include <cf.h>
713575b131SDoug MacEachern
72a0f68ed2SDoug MacEachern#include <sys/ldr.h>
73a0f68ed2SDoug MacEachern
74e92da524SDoug MacEachern/* for net_interface_config ipv6 */
75e92da524SDoug MacEachern#include <sys/ioctl.h>
76e92da524SDoug MacEachern#include <netinet/in6_var.h>
77e92da524SDoug MacEachern
7839fef6c3SDoug MacEachern/* for getkerninfo */
7939fef6c3SDoug MacEachern#include <sys/kinfo.h>
8039fef6c3SDoug MacEachern
81c9266208SDoug MacEachern/* not defined in aix 4.3 */
82c9266208SDoug MacEachern#ifndef SBITS
83c9266208SDoug MacEachern#define SBITS 16
84c9266208SDoug MacEachern#endif
85c9266208SDoug MacEachern
86bee745afSDoug MacEachern#ifndef PTHRDSINFO_RUSAGE_START
87bee745afSDoug MacEachern#define PTHRDSINFO_RUSAGE_START   0x00000001
88bee745afSDoug MacEachern#define PTHRDSINFO_RUSAGE_STOP    0x00000002
89bee745afSDoug MacEachern#define PTHRDSINFO_RUSAGE_COLLECT 0x00000004
90bee745afSDoug MacEachern#endif
91bee745afSDoug MacEachern
92c9266208SDoug MacEachern/*
93c9266208SDoug MacEachern * from libperfstat.h:
94c9266208SDoug MacEachern * "To calculate the load average, divide the numbers by (1<<SBITS).
95c9266208SDoug MacEachern *  SBITS is defined in <sys/proc.h>."
96c9266208SDoug MacEachern */
97c9266208SDoug MacEachern#define FIXED_TO_DOUBLE(x) (((double)x) / (1<<SBITS))
98dffe0da8SDoug MacEachern
99dffe0da8SDoug MacEachern/* these offsets wont change so just lookup them up during open */
100dffe0da8SDoug MacEachernstatic int get_koffsets(sigar_t *sigar)
101dffe0da8SDoug MacEachern{
102dffe0da8SDoug MacEachern    int i;
103dffe0da8SDoug MacEachern    /* see man knlist and nlist.h */
104dffe0da8SDoug MacEachern    struct nlist klist[] = {
105dffe0da8SDoug MacEachern        {"avenrun", 0, 0, 0, 0, 0}, /* KOFFSET_LOADAVG */
106dffe0da8SDoug MacEachern        {"v", 0, 0, 0, 0, 0}, /* KOFFSET_VAR */
107dffe0da8SDoug MacEachern        {"sysinfo", 0, 0, 0, 0, 0}, /* KOFFSET_SYSINFO */
108dffe0da8SDoug MacEachern        {"ifnet", 0, 0, 0, 0, 0}, /* KOFFSET_IFNET */
109dffe0da8SDoug MacEachern        {"vmminfo", 0, 0, 0, 0, 0}, /* KOFFSET_VMINFO */
110dffe0da8SDoug MacEachern        {"cpuinfo", 0, 0, 0, 0, 0}, /* KOFFSET_CPUINFO */
111b1815c1dSDoug MacEachern        {"tcb", 0, 0, 0, 0, 0}, /* KOFFSET_TCB */
11202959a80SDoug MacEachern        {"arptabsize", 0, 0, 0, 0, 0}, /* KOFFSET_ARPTABSIZE */
11302959a80SDoug MacEachern        {"arptabp", 0, 0, 0, 0, 0}, /* KOFFSET_ARPTABP */
114dffe0da8SDoug MacEachern        {NULL, 0, 0, 0, 0, 0}
115dffe0da8SDoug MacEachern    };
116dffe0da8SDoug MacEachern
117dffe0da8SDoug MacEachern    if (knlist(klist,
118dffe0da8SDoug MacEachern               sizeof(klist) / sizeof(klist[0]),
119dffe0da8SDoug MacEachern               sizeof(klist[0])) != 0)
120dffe0da8SDoug MacEachern    {
121dffe0da8SDoug MacEachern        return errno;
122dffe0da8SDoug MacEachern    }
123dffe0da8SDoug MacEachern
124dffe0da8SDoug MacEachern    for (i=0; i<KOFFSET_MAX; i++) {
125dffe0da8SDoug MacEachern        sigar->koffsets[i] = klist[i].n_value;
126dffe0da8SDoug MacEachern    }
127829a4c03STrond Norbye
128dffe0da8SDoug MacEachern    return SIGAR_OK;
129dffe0da8SDoug MacEachern}
130dffe0da8SDoug MacEachern
131dffe0da8SDoug MacEachernstatic int kread(sigar_t *sigar, void *data, int size, long offset)
132dffe0da8SDoug MacEachern{
133dffe0da8SDoug MacEachern    if (sigar->kmem < 0) {
134dffe0da8SDoug MacEachern        return SIGAR_EPERM_KMEM;
135dffe0da8SDoug MacEachern    }
136dffe0da8SDoug MacEachern
137dffe0da8SDoug MacEachern    if (lseek(sigar->kmem, offset, SEEK_SET) != offset) {
138dffe0da8SDoug MacEachern        return errno;
139dffe0da8SDoug MacEachern    }
140dffe0da8SDoug MacEachern
141dffe0da8SDoug MacEachern    if (read(sigar->kmem, data, size) != size) {
142dffe0da8SDoug MacEachern        return errno;
143dffe0da8SDoug MacEachern    }
144dffe0da8SDoug MacEachern
145dffe0da8SDoug MacEachern    return SIGAR_OK;
146dffe0da8SDoug MacEachern}
147dffe0da8SDoug MacEachern
1484c587388SDoug MacEachernstatic int sigar_thread_rusage(struct rusage *usage, int mode)
1494c587388SDoug MacEachern{
1504c587388SDoug MacEachern    return pthread_getrusage_np(pthread_self(), usage, mode);
1514c587388SDoug MacEachern}
1524c587388SDoug MacEachern
1534c587388SDoug MacEachernstatic int sigar_perfstat_memory(perfstat_memory_total_t *memory)
1544c587388SDoug MacEachern{
1554c587388SDoug MacEachern    return perfstat_memory_total(NULL, memory, sizeof(*memory), 1);
1564c587388SDoug MacEachern}
1574c587388SDoug MacEachern
1584c587388SDoug MacEachernstatic int sigar_perfstat_cpu(perfstat_cpu_total_t *cpu_total)
1594c587388SDoug MacEachern{
1604c587388SDoug MacEachern    return perfstat_cpu_total(NULL, cpu_total, sizeof(*cpu_total), 1);
1614c587388SDoug MacEachern}
1624c587388SDoug MacEachern
163dffe0da8SDoug MacEachernint sigar_os_open(sigar_t **sigar)
164dffe0da8SDoug MacEachern{
165dffe0da8SDoug MacEachern    int status, i;
166dffe0da8SDoug MacEachern    int kmem = -1;
167471d4bb0SDoug MacEachern    struct utsname name;
168dffe0da8SDoug MacEachern
169dffe0da8SDoug MacEachern    kmem = open("/dev/kmem", O_RDONLY);
170dffe0da8SDoug MacEachern
171dffe0da8SDoug MacEachern    *sigar = malloc(sizeof(**sigar));
172dffe0da8SDoug MacEachern
173dffe0da8SDoug MacEachern    (*sigar)->getprocfd = NULL; /*XXX*/
174dffe0da8SDoug MacEachern    (*sigar)->kmem = kmem;
175dffe0da8SDoug MacEachern    (*sigar)->pagesize = 0;
1766fed44d4SDoug MacEachern    (*sigar)->ticks = sysconf(_SC_CLK_TCK);
177dffe0da8SDoug MacEachern    (*sigar)->boot_time = 0;
178dffe0da8SDoug MacEachern    (*sigar)->last_pid = -1;
179dffe0da8SDoug MacEachern    (*sigar)->pinfo = NULL;
180dffe0da8SDoug MacEachern    (*sigar)->cpuinfo = NULL;
181dffe0da8SDoug MacEachern    (*sigar)->cpuinfo_size = 0;
182dffe0da8SDoug MacEachern    SIGAR_ZERO(&(*sigar)->swaps);
183dffe0da8SDoug MacEachern
184dffe0da8SDoug MacEachern    i = getpagesize();
185dffe0da8SDoug MacEachern    while ((i >>= 1) > 0) {
186dffe0da8SDoug MacEachern        (*sigar)->pagesize++;
187dffe0da8SDoug MacEachern    }
188dffe0da8SDoug MacEachern
189dffe0da8SDoug MacEachern    if (kmem > 0) {
190dffe0da8SDoug MacEachern        if ((status = get_koffsets(*sigar)) != SIGAR_OK) {
1914867aeb2SDoug MacEachern            /* libperfstat only mode (aix 6) */
1924867aeb2SDoug MacEachern            close((*sigar)->kmem);
1934867aeb2SDoug MacEachern            (*sigar)->kmem = -1;
194dffe0da8SDoug MacEachern        }
195dffe0da8SDoug MacEachern    }
196dffe0da8SDoug MacEachern
1979a00bf0cSDoug MacEachern    (*sigar)->cpu_mhz = -1;
1989a00bf0cSDoug MacEachern
1993575b131SDoug MacEachern    (*sigar)->model[0] = '\0';
2003575b131SDoug MacEachern
201471d4bb0SDoug MacEachern    uname(&name);
202471d4bb0SDoug MacEachern
203471d4bb0SDoug MacEachern    (*sigar)->aix_version = atoi(name.version);
204471d4bb0SDoug MacEachern
205bee745afSDoug MacEachern    (*sigar)->thrusage = PTHRDSINFO_RUSAGE_STOP;
206bee745afSDoug MacEachern
2075630d9a4SDoug MacEachern    (*sigar)->diskmap = NULL;
2085630d9a4SDoug MacEachern
209dffe0da8SDoug MacEachern    return SIGAR_OK;
210dffe0da8SDoug MacEachern}
211dffe0da8SDoug MacEachern
212dffe0da8SDoug MacEachernstatic void swaps_free(swaps_t *swaps);
213dffe0da8SDoug MacEachern
214dffe0da8SDoug MacEachernint sigar_os_close(sigar_t *sigar)
215dffe0da8SDoug MacEachern{
216dffe0da8SDoug MacEachern    swaps_free(&sigar->swaps);
217dffe0da8SDoug MacEachern    if (sigar->kmem > 0) {
218dffe0da8SDoug MacEachern        close(sigar->kmem);
219dffe0da8SDoug MacEachern    }
220dffe0da8SDoug MacEachern    if (sigar->pinfo) {
221dffe0da8SDoug MacEachern        free(sigar->pinfo);
222dffe0da8SDoug MacEachern    }
223dffe0da8SDoug MacEachern    if (sigar->cpuinfo) {
224dffe0da8SDoug MacEachern        free(sigar->cpuinfo);
225dffe0da8SDoug MacEachern    }
2265630d9a4SDoug MacEachern    if (sigar->diskmap) {
2275630d9a4SDoug MacEachern        sigar_cache_destroy(sigar->diskmap);
2285630d9a4SDoug MacEachern    }
229bee745afSDoug MacEachern    if (sigar->thrusage == PTHRDSINFO_RUSAGE_START) {
230bee745afSDoug MacEachern        struct rusage usage;
2314c587388SDoug MacEachern        sigar_thread_rusage(&usage,
2324c587388SDoug MacEachern                            PTHRDSINFO_RUSAGE_STOP);
233bee745afSDoug MacEachern    }
234dffe0da8SDoug MacEachern    free(sigar);
235dffe0da8SDoug MacEachern    return SIGAR_OK;
236dffe0da8SDoug MacEachern}
237dffe0da8SDoug MacEachern
238b9144d17SDoug MacEachernchar *sigar_os_error_string(sigar_t *sigar, int err)
239dffe0da8SDoug MacEachern{
240dffe0da8SDoug MacEachern    switch (err) {
241dffe0da8SDoug MacEachern      case SIGAR_EPERM_KMEM:
242dffe0da8SDoug MacEachern        return "Failed to open /dev/kmem for reading";
243dffe0da8SDoug MacEachern      default:
244dffe0da8SDoug MacEachern        return NULL;
245dffe0da8SDoug MacEachern    }
246dffe0da8SDoug MacEachern}
247dffe0da8SDoug MacEachern
248dffe0da8SDoug MacEachern#define PAGESHIFT(v) \
249dffe0da8SDoug MacEachern    ((v) << sigar->pagesize)
250dffe0da8SDoug MacEachern
251dffe0da8SDoug MacEachernint sigar_mem_get(sigar_t *sigar, sigar_mem_t *mem)
252dffe0da8SDoug MacEachern{
2535ba9b0eeSDoug MacEachern    int status;
2544c587388SDoug MacEachern    perfstat_memory_total_t minfo;
255127099cdSDoug MacEachern    sigar_uint64_t kern;
256dffe0da8SDoug MacEachern
2574c587388SDoug MacEachern    if (sigar_perfstat_memory(&minfo) == 1) {
2584c587388SDoug MacEachern        mem->total = PAGESHIFT(minfo.real_total);
2594c587388SDoug MacEachern        mem->free  = PAGESHIFT(minfo.real_free);
260127099cdSDoug MacEachern        kern = PAGESHIFT(minfo.numperm); /* number of pages in file cache */
261dffe0da8SDoug MacEachern    }
2625ba9b0eeSDoug MacEachern    else {
2634c587388SDoug MacEachern        return errno;
264829a4c03STrond Norbye    }
265dffe0da8SDoug MacEachern
2665ba9b0eeSDoug MacEachern    mem->used = mem->total - mem->free;
267127099cdSDoug MacEachern    mem->actual_used = mem->used - kern;
268127099cdSDoug MacEachern    mem->actual_free = mem->free + kern;
269829a4c03STrond Norbye
270dffe0da8SDoug MacEachern    sigar_mem_calc_ram(sigar, mem);
271dffe0da8SDoug MacEachern
272dffe0da8SDoug MacEachern    return SIGAR_OK;
273dffe0da8SDoug MacEachern}
274dffe0da8SDoug MacEachern
275dffe0da8SDoug MacEachernstatic void swaps_free(swaps_t *swaps)
276dffe0da8SDoug MacEachern{
277dffe0da8SDoug MacEachern    if (swaps->num) {
278dffe0da8SDoug MacEachern        int i;
279dffe0da8SDoug MacEachern
280dffe0da8SDoug MacEachern        for (i=0; i<swaps->num; i++) {
281dffe0da8SDoug MacEachern            free(swaps->devs[i]);
282dffe0da8SDoug MacEachern        }
283dffe0da8SDoug MacEachern
284dffe0da8SDoug MacEachern        free(swaps->devs);
285dffe0da8SDoug MacEachern
286dffe0da8SDoug MacEachern        swaps->num = 0;
287dffe0da8SDoug MacEachern    }
288dffe0da8SDoug MacEachern}
289dffe0da8SDoug MacEachern
290dffe0da8SDoug MacEachern/*
291dffe0da8SDoug MacEachern * there is no public api for parsing this file.
292dffe0da8SDoug MacEachern * well, there is something, but its super ugly and requires
293dffe0da8SDoug MacEachern * linking 2 static libraries (libodm and something else)
294dffe0da8SDoug MacEachern * maybe will switch to that if it can add value elsewhere too.
295dffe0da8SDoug MacEachern */
296dffe0da8SDoug MacEachern#define SWAPSPACES "/etc/swapspaces"
297dffe0da8SDoug MacEachern
298dffe0da8SDoug MacEachernstatic int swaps_get(swaps_t *swaps)
299dffe0da8SDoug MacEachern{
300dffe0da8SDoug MacEachern    FILE *fp;
301dffe0da8SDoug MacEachern    char buf[512];
302dffe0da8SDoug MacEachern    char *ptr;
303dffe0da8SDoug MacEachern    struct stat statbuf;
304dffe0da8SDoug MacEachern
305dffe0da8SDoug MacEachern    if (stat(SWAPSPACES, &statbuf) < 0) {
306dffe0da8SDoug MacEachern        return errno;
307dffe0da8SDoug MacEachern    }
308dffe0da8SDoug MacEachern
309dffe0da8SDoug MacEachern    /* only re-parse if file has changed */
310dffe0da8SDoug MacEachern    if (swaps->mtime == statbuf.st_mtime) {
311dffe0da8SDoug MacEachern        return 0;
312dffe0da8SDoug MacEachern    }
313dffe0da8SDoug MacEachern
314dffe0da8SDoug MacEachern    swaps->mtime = statbuf.st_mtime;
315dffe0da8SDoug MacEachern
316dffe0da8SDoug MacEachern    /* easier to just start from scratch */
317dffe0da8SDoug MacEachern    swaps_free(swaps);
318dffe0da8SDoug MacEachern
319dffe0da8SDoug MacEachern    if (!(fp = fopen(SWAPSPACES, "r"))) {
320dffe0da8SDoug MacEachern        return errno;
321dffe0da8SDoug MacEachern    }
322dffe0da8SDoug MacEachern
323dffe0da8SDoug MacEachern    while ((ptr = fgets(buf, sizeof(buf), fp))) {
324dffe0da8SDoug MacEachern        if (!isalpha(*ptr)) {
325dffe0da8SDoug MacEachern            continue;
326dffe0da8SDoug MacEachern        }
327dffe0da8SDoug MacEachern
328dffe0da8SDoug MacEachern        if (strchr(ptr, ':')) {
329dffe0da8SDoug MacEachern            int len;
330dffe0da8SDoug MacEachern
331dffe0da8SDoug MacEachern            ptr = fgets(buf, sizeof(buf), fp);
332dffe0da8SDoug MacEachern
333dffe0da8SDoug MacEachern            while (isspace(*ptr)) {
334dffe0da8SDoug MacEachern                ++ptr;
335dffe0da8SDoug MacEachern            }
336dffe0da8SDoug MacEachern
337dffe0da8SDoug MacEachern            if (strncmp(ptr, "dev", 3)) {
338dffe0da8SDoug MacEachern                continue;
339dffe0da8SDoug MacEachern            }
340dffe0da8SDoug MacEachern            ptr += 3;
341dffe0da8SDoug MacEachern            while (isspace(*ptr) || (*ptr == '=')) {
342dffe0da8SDoug MacEachern                ++ptr;
343dffe0da8SDoug MacEachern            }
344dffe0da8SDoug MacEachern
345dffe0da8SDoug MacEachern            len = strlen(ptr);
346dffe0da8SDoug MacEachern            ptr[len-1] = '\0'; /* -1 == chomp \n */
347dffe0da8SDoug MacEachern
348dffe0da8SDoug MacEachern            swaps->devs = realloc(swaps->devs, swaps->num+1 * sizeof(char *));
349dffe0da8SDoug MacEachern            swaps->devs[swaps->num] = malloc(len);
350dffe0da8SDoug MacEachern            memcpy(swaps->devs[swaps->num], ptr, len);
351dffe0da8SDoug MacEachern
352dffe0da8SDoug MacEachern            swaps->num++;
353dffe0da8SDoug MacEachern        }
354dffe0da8SDoug MacEachern    }
355dffe0da8SDoug MacEachern
356dffe0da8SDoug MacEachern    fclose(fp);
357dffe0da8SDoug MacEachern
358dffe0da8SDoug MacEachern    return 0;
359dffe0da8SDoug MacEachern}
360dffe0da8SDoug MacEachern
361829a4c03STrond Norbye/*
362dffe0da8SDoug MacEachern * documented in aix tech ref,
363dffe0da8SDoug MacEachern * but this prototype is not in any friggin header file.
364dffe0da8SDoug MacEachern * struct pginfo is in sys/vminfo.h
365dffe0da8SDoug MacEachern */
366dffe0da8SDoug MacEachern
367dffe0da8SDoug MacEachernint swapqry(char *path, struct pginfo *info);
368dffe0da8SDoug MacEachern
369ffc18694SDoug MacEachernstatic int sigar_swap_get_swapqry(sigar_t *sigar, sigar_swap_t *swap)
370dffe0da8SDoug MacEachern{
371dffe0da8SDoug MacEachern    int status, i;
372dffe0da8SDoug MacEachern
373dffe0da8SDoug MacEachern    if ((status = swaps_get(&sigar->swaps)) != SIGAR_OK) {
374dffe0da8SDoug MacEachern        return status;
375dffe0da8SDoug MacEachern    }
376dffe0da8SDoug MacEachern
377426d2d9eSDoug MacEachern    if (SIGAR_LOG_IS_DEBUG(sigar)) {
378426d2d9eSDoug MacEachern        sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
379426d2d9eSDoug MacEachern                         "[swap] pagesize=%d, shift=%d",
380426d2d9eSDoug MacEachern                         getpagesize(), sigar->pagesize);
381426d2d9eSDoug MacEachern    }
382426d2d9eSDoug MacEachern
383dffe0da8SDoug MacEachern    swap->total = swap->free = 0;
384dffe0da8SDoug MacEachern
385dffe0da8SDoug MacEachern    for (i=0; i<sigar->swaps.num; i++) {
386dffe0da8SDoug MacEachern        struct pginfo info;
387dffe0da8SDoug MacEachern
388dffe0da8SDoug MacEachern        status = swapqry(sigar->swaps.devs[i], &info);
389dffe0da8SDoug MacEachern
390dffe0da8SDoug MacEachern        if (status != 0) {
391310cf063SDoug MacEachern            if (SIGAR_LOG_IS_DEBUG(sigar)) {
392310cf063SDoug MacEachern                sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
393310cf063SDoug MacEachern                                 "[swap] swapqry(%s) failed: %s",
394310cf063SDoug MacEachern                                 sigar->swaps.devs[i],
395310cf063SDoug MacEachern                                 sigar_strerror(sigar, errno));
396310cf063SDoug MacEachern            }
397310cf063SDoug MacEachern            continue;
398dffe0da8SDoug MacEachern        }
399dffe0da8SDoug MacEachern
400426d2d9eSDoug MacEachern        if (SIGAR_LOG_IS_DEBUG(sigar)) {
401426d2d9eSDoug MacEachern            sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
402426d2d9eSDoug MacEachern                             "[swap] %s total=%d/%d, free=%d/%d",
403426d2d9eSDoug MacEachern                             sigar->swaps.devs[i],
404426d2d9eSDoug MacEachern                             info.size, PAGESHIFT(info.size),
405426d2d9eSDoug MacEachern                             info.free, PAGESHIFT(info.free));
406426d2d9eSDoug MacEachern        }
407426d2d9eSDoug MacEachern
408dffe0da8SDoug MacEachern        swap->total += PAGESHIFT(info.size); /* lsps -a */
409dffe0da8SDoug MacEachern        swap->free  += PAGESHIFT(info.free);
410dffe0da8SDoug MacEachern    }
411dffe0da8SDoug MacEachern
412dffe0da8SDoug MacEachern    swap->used = swap->total - swap->free;
413dffe0da8SDoug MacEachern
414dffe0da8SDoug MacEachern    return SIGAR_OK;
415dffe0da8SDoug MacEachern}
416dffe0da8SDoug MacEachern
417ffc18694SDoug MacEachern#define SWAP_DEV(ps) \
418ffc18694SDoug MacEachern   ((ps.type == LV_PAGING) ? \
4194c587388SDoug MacEachern     ps.u.lv_paging.vgname : \
4204c587388SDoug MacEachern     ps.u.nfs_paging.filename)
421ffc18694SDoug MacEachern
422ffc18694SDoug MacEachern#define SWAP_MB_TO_BYTES(v) ((v) * (1024 * 1024))
423ffc18694SDoug MacEachern
4244c587388SDoug MacEachernint sigar_swap_get(sigar_t *sigar, sigar_swap_t *swap)
425ffc18694SDoug MacEachern{
42676e8f77bSDoug MacEachern    perfstat_memory_total_t minfo;
427ffc18694SDoug MacEachern    perfstat_pagingspace_t ps;
428ffc18694SDoug MacEachern    perfstat_id_t id;
429ffc18694SDoug MacEachern
430ffc18694SDoug MacEachern    id.name[0] = '\0';
431ffc18694SDoug MacEachern
432ffc18694SDoug MacEachern    SIGAR_ZERO(swap);
433ffc18694SDoug MacEachern
434ffc18694SDoug MacEachern    do {
4354c587388SDoug MacEachern        if (perfstat_pagingspace(&id, &ps, sizeof(ps), 1) != 1) {
436ffc18694SDoug MacEachern            if (SIGAR_LOG_IS_DEBUG(sigar)) {
437ffc18694SDoug MacEachern                sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
438ffc18694SDoug MacEachern                                 "[swap] dev=%s query failed: %s",
439ffc18694SDoug MacEachern                                 SWAP_DEV(ps),
440ffc18694SDoug MacEachern                                 sigar_strerror(sigar, errno));
441ffc18694SDoug MacEachern            }
442ffc18694SDoug MacEachern            continue;
443ffc18694SDoug MacEachern        }
444ffc18694SDoug MacEachern        if (SIGAR_LOG_IS_DEBUG(sigar)) {
445ffc18694SDoug MacEachern            sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
446d87f4e50SDoug MacEachern                             "[swap] dev=%s: active=%s, "
447d87f4e50SDoug MacEachern                             "total=%lluMb, used=%lluMb",
448d87f4e50SDoug MacEachern                             SWAP_DEV(ps),
449d87f4e50SDoug MacEachern                             ((ps.active == 1) ? "yes" : "no"),
450d87f4e50SDoug MacEachern                             ps.mb_size, ps.mb_used);
451d87f4e50SDoug MacEachern        }
452d87f4e50SDoug MacEachern        if (ps.active != 1) {
453d87f4e50SDoug MacEachern            continue;
454ffc18694SDoug MacEachern        }
455ffc18694SDoug MacEachern        /* convert MB sizes to bytes */
456ffc18694SDoug MacEachern        swap->total += SWAP_MB_TO_BYTES(ps.mb_size);
457ffc18694SDoug MacEachern        swap->used  += SWAP_MB_TO_BYTES(ps.mb_used);
458ffc18694SDoug MacEachern    } while (id.name[0] != '\0');
459ffc18694SDoug MacEachern
460ffc18694SDoug MacEachern    swap->free = swap->total - swap->used;
461ffc18694SDoug MacEachern
4624c587388SDoug MacEachern    if (sigar_perfstat_memory(&minfo) == 1) {
46376e8f77bSDoug MacEachern        swap->page_in = minfo.pgins;
46476e8f77bSDoug MacEachern        swap->page_out = minfo.pgouts;
46576e8f77bSDoug MacEachern    }
466ffc18694SDoug MacEachern    else {
4674c587388SDoug MacEachern        swap->page_in = swap->page_out = -1;
468ffc18694SDoug MacEachern    }
469e1b339d4SSteve Watanabe
470e1b339d4SSteve Watanabe    swap->allocstall = -1;
471e1b339d4SSteve Watanabe    swap->allocstall_dma = -1;
472e1b339d4SSteve Watanabe    swap->allocstall_dma32 = -1;
473e1b339d4SSteve Watanabe    swap->allocstall_normal = -1;
474e1b339d4SSteve Watanabe    swap->allocstall_movable = -1;
475e1b339d4SSteve Watanabe
4764c587388SDoug MacEachern    return SIGAR_OK;
477ffc18694SDoug MacEachern}
478ffc18694SDoug MacEachern
479dffe0da8SDoug MacEachernint sigar_cpu_get(sigar_t *sigar, sigar_cpu_t *cpu)
480dffe0da8SDoug MacEachern{
481dffe0da8SDoug MacEachern    int i, status;
482dffe0da8SDoug MacEachern    struct sysinfo data;
483c9056645SDoug MacEachern    perfstat_cpu_total_t cpu_data;
484c9056645SDoug MacEachern
4854c587388SDoug MacEachern    if (sigar_perfstat_cpu(&cpu_data) == 1) {
4864c587388SDoug MacEachern        cpu->user  = SIGAR_TICK2MSEC(cpu_data.user);
4874c587388SDoug MacEachern        cpu->nice  = SIGAR_FIELD_NOTIMPL; /* N/A */
4884c587388SDoug MacEachern        cpu->sys   = SIGAR_TICK2MSEC(cpu_data.sys);
4894c587388SDoug MacEachern        cpu->idle  = SIGAR_TICK2MSEC(cpu_data.idle);
4904c587388SDoug MacEachern        cpu->wait  = SIGAR_TICK2MSEC(cpu_data.wait);
4914c587388SDoug MacEachern        cpu->irq = 0; /*N/A*/
4924c587388SDoug MacEachern        cpu->soft_irq = 0; /*N/A*/
4934c587388SDoug MacEachern        cpu->stolen = 0; /*N/A*/
4944c587388SDoug MacEachern        cpu->total = cpu->user + cpu->sys + cpu->idle + cpu->wait;
4954c587388SDoug MacEachern        return SIGAR_OK;
496c9056645SDoug MacEachern    }
4974c587388SDoug MacEachern    else {
4984c587388SDoug MacEachern        return errno;
499dffe0da8SDoug MacEachern    }
500dffe0da8SDoug MacEachern}
501dffe0da8SDoug MacEachern
502dffe0da8SDoug MacEachern/*
503dffe0da8SDoug MacEachern * other possible metrics we could add:
504dffe0da8SDoug MacEachern * struct cpuinfo {
505dffe0da8SDoug MacEachern *       long    cpu[CPU_NTIMES];
506dffe0da8SDoug MacEachern *       long    pswitch;
507dffe0da8SDoug MacEachern *       long    syscall;
508dffe0da8SDoug MacEachern *       long    sysread;
509dffe0da8SDoug MacEachern *       long    syswrite;
510dffe0da8SDoug MacEachern *       long    sysfork;
511dffe0da8SDoug MacEachern *       long    sysexec;
512dffe0da8SDoug MacEachern *       long    readch;
513dffe0da8SDoug MacEachern *       long    writech;
514dffe0da8SDoug MacEachern *       long    iget;
515dffe0da8SDoug MacEachern *       long    namei;
516dffe0da8SDoug MacEachern *       long    dirblk;
517dffe0da8SDoug MacEachern *       long    msg;
518dffe0da8SDoug MacEachern *       long    sema;
519dffe0da8SDoug MacEachern *       long    bread;
520dffe0da8SDoug MacEachern *       long    bwrite;
521dffe0da8SDoug MacEachern *       long    lread;
522dffe0da8SDoug MacEachern *       long    lwrite;
523dffe0da8SDoug MacEachern *       long    phread;
524dffe0da8SDoug MacEachern *       long    phwrite;
525dffe0da8SDoug MacEachern * };
526dffe0da8SDoug MacEachern */
527dffe0da8SDoug MacEachern
52887b502d7SDoug MacEachern
529829f9310SDoug MacEachernstatic int boot_time(sigar_t *sigar, time_t *time)
530dffe0da8SDoug MacEachern{
531829f9310SDoug MacEachern    int fd;
532dffe0da8SDoug MacEachern    struct utmp data;
533dffe0da8SDoug MacEachern
534829f9310SDoug MacEachern    if ((fd = open(UTMP_FILE, O_RDONLY)) < 0) {
535829f9310SDoug MacEachern        return errno;
536829f9310SDoug MacEachern    }
537829f9310SDoug MacEachern
538dffe0da8SDoug MacEachern    do {
539dffe0da8SDoug MacEachern        if (read(fd, &data, sizeof(data)) != sizeof(data)) {
540829f9310SDoug MacEachern            int status = errno;
541829f9310SDoug MacEachern            close(fd);
542829f9310SDoug MacEachern            return status;
543dffe0da8SDoug MacEachern        }
544dffe0da8SDoug MacEachern    } while (data.ut_type != BOOT_TIME);
545dffe0da8SDoug MacEachern
546dffe0da8SDoug MacEachern    *time = data.ut_time;
547dffe0da8SDoug MacEachern
548829f9310SDoug MacEachern    close(fd);
549dffe0da8SDoug MacEachern
550dffe0da8SDoug MacEachern    return SIGAR_OK;
551dffe0da8SDoug MacEachern}
552dffe0da8SDoug MacEachern
5535ba12f56SDoug MacEachern#define WHOCPY(dest, src) \
5545ba12f56SDoug MacEachern    SIGAR_SSTRCPY(dest, src); \
5555ba12f56SDoug MacEachern    if (sizeof(src) < sizeof(dest)) \
556829f9310SDoug MacEachern        dest[sizeof(dest)-1] = '\0'
5575ba12f56SDoug MacEachern
558829f9310SDoug MacEachernstatic int sigar_who_utmp(sigar_t *sigar,
559829f9310SDoug MacEachern                          sigar_who_list_t *wholist)
5605ba12f56SDoug MacEachern{
5615ba12f56SDoug MacEachern    struct utmp ut;
562829f9310SDoug MacEachern    FILE *fp;
5635ba12f56SDoug MacEachern
564829f9310SDoug MacEachern    if (!(fp = fopen(UTMP_FILE, "r"))) {
565829f9310SDoug MacEachern        return errno;
5665ba12f56SDoug MacEachern    }
5675ba12f56SDoug MacEachern
5685ba12f56SDoug MacEachern    while (fread(&ut, sizeof(ut), 1, fp) == 1) {
5695ba12f56SDoug MacEachern        sigar_who_t *who;
5705ba12f56SDoug MacEachern
5715ba12f56SDoug MacEachern        if (*ut.ut_name == '\0') {
5725ba12f56SDoug MacEachern            continue;
5735ba12f56SDoug MacEachern        }
5745ba12f56SDoug MacEachern
5755ba12f56SDoug MacEachern        if (ut.ut_type != USER_PROCESS) {
5765ba12f56SDoug MacEachern            continue;
5775ba12f56SDoug MacEachern        }
5785ba12f56SDoug MacEachern
5795ba12f56SDoug MacEachern        SIGAR_WHO_LIST_GROW(wholist);
5805ba12f56SDoug MacEachern        who = &wholist->data[wholist->number++];
5815ba12f56SDoug MacEachern
5825ba12f56SDoug MacEachern        WHOCPY(who->user, ut.ut_user);
5835ba12f56SDoug MacEachern        WHOCPY(who->device, ut.ut_line);
5845ba12f56SDoug MacEachern        WHOCPY(who->host, ut.ut_host);
5855ba12f56SDoug MacEachern
5865ba12f56SDoug MacEachern        who->time = ut.ut_time;
5875ba12f56SDoug MacEachern    }
5885ba12f56SDoug MacEachern
5895ba12f56SDoug MacEachern    fclose(fp);
5905ba12f56SDoug MacEachern
591829f9310SDoug MacEachern    return SIGAR_OK;
5925ba12f56SDoug MacEachern}
5935ba12f56SDoug MacEachern
594ad433cf3SDoug MacEachernint sigar_os_proc_list_get(sigar_t *sigar,
595ad433cf3SDoug MacEachern                           sigar_proc_list_t *proclist)
596dffe0da8SDoug MacEachern{
597dffe0da8SDoug MacEachern    pid_t pid = 0;
598dffe0da8SDoug MacEachern    struct procsinfo info;
599dffe0da8SDoug MacEachern
600dffe0da8SDoug MacEachern    for (;;) {
601dffe0da8SDoug MacEachern        int num = getprocs(&info, sizeof(info),
602dffe0da8SDoug MacEachern                           NULL, 0, &pid, 1);
603dffe0da8SDoug MacEachern
604dffe0da8SDoug MacEachern        if (num == 0) {
605dffe0da8SDoug MacEachern            break;
606dffe0da8SDoug MacEachern        }
607dffe0da8SDoug MacEachern
608dffe0da8SDoug MacEachern        SIGAR_PROC_LIST_GROW(proclist);
609dffe0da8SDoug MacEachern
610dffe0da8SDoug MacEachern        proclist->data[proclist->number++] = info.pi_pid;
611dffe0da8SDoug MacEachern    }
612dffe0da8SDoug MacEachern
613dffe0da8SDoug MacEachern    return SIGAR_OK;
614dffe0da8SDoug MacEachern}
615dffe0da8SDoug MacEachern
616dffe0da8SDoug MacEachernstatic int sigar_getprocs(sigar_t *sigar, sigar_pid_t pid)
617dffe0da8SDoug MacEachern{
618dffe0da8SDoug MacEachern    int status, num;
619dffe0da8SDoug MacEachern    time_t timenow = time(NULL);
620dffe0da8SDoug MacEachern
621dffe0da8SDoug MacEachern    if (sigar->pinfo == NULL) {
622dffe0da8SDoug MacEachern        sigar->pinfo = malloc(sizeof(*sigar->pinfo));
623dffe0da8SDoug MacEachern    }
624dffe0da8SDoug MacEachern
625dffe0da8SDoug MacEachern    if (sigar->last_pid == pid) {
626dffe0da8SDoug MacEachern        if ((timenow - sigar->last_getprocs) < SIGAR_LAST_PROC_EXPIRE) {
627dffe0da8SDoug MacEachern            return SIGAR_OK;
628dffe0da8SDoug MacEachern        }
629dffe0da8SDoug MacEachern    }
630dffe0da8SDoug MacEachern
631dffe0da8SDoug MacEachern    sigar->last_pid = pid;
632dffe0da8SDoug MacEachern    sigar->last_getprocs = timenow;
633dffe0da8SDoug MacEachern
634dffe0da8SDoug MacEachern    num = getprocs(sigar->pinfo, sizeof(*sigar->pinfo),
635dffe0da8SDoug MacEachern                   NULL, 0, &pid, 1);
636dffe0da8SDoug MacEachern
637dffe0da8SDoug MacEachern    if (num != 1) {
638dffe0da8SDoug MacEachern        return ESRCH;
639dffe0da8SDoug MacEachern    }
640dffe0da8SDoug MacEachern
641dffe0da8SDoug MacEachern    return SIGAR_OK;
642dffe0da8SDoug MacEachern}
643dffe0da8SDoug MacEachern
644dffe0da8SDoug MacEachernint sigar_proc_mem_get(sigar_t *sigar, sigar_pid_t pid,
645dffe0da8SDoug MacEachern                       sigar_proc_mem_t *procmem)
646dffe0da8SDoug MacEachern{
647dffe0da8SDoug MacEachern    int status = sigar_getprocs(sigar, pid);
64892a33c7cSDoug MacEachern    struct procsinfo64 *pinfo = sigar->pinfo;
649dffe0da8SDoug MacEachern
650dffe0da8SDoug MacEachern    if (status != SIGAR_OK) {
651dffe0da8SDoug MacEachern        return status;
652dffe0da8SDoug MacEachern    }
653dffe0da8SDoug MacEachern
654e63e0ff4SDoug MacEachern    procmem->size  = PAGESHIFT(pinfo->pi_size); /* XXX fold in pi_dvm ? */
655dffe0da8SDoug MacEachern    procmem->share = PAGESHIFT(pinfo->pi_sdsize);
656e63e0ff4SDoug MacEachern    procmem->resident = PAGESHIFT(pinfo->pi_drss + pinfo->pi_trss);
657dffe0da8SDoug MacEachern
65853015716SDoug MacEachern    procmem->minor_faults = pinfo->pi_minflt;
65953015716SDoug MacEachern    procmem->major_faults = pinfo->pi_majflt;
66053015716SDoug MacEachern    procmem->page_faults =
66153015716SDoug MacEachern        procmem->minor_faults +
66253015716SDoug MacEachern        procmem->major_faults;
66353015716SDoug MacEachern
664dffe0da8SDoug MacEachern    return SIGAR_OK;
665dffe0da8SDoug MacEachern}
666dffe0da8SDoug MacEachern
667dffe0da8SDoug MacEachernint sigar_proc_time_get(sigar_t *sigar, sigar_pid_t pid,
668dffe0da8SDoug MacEachern                        sigar_proc_time_t *proctime)
669dffe0da8SDoug MacEachern{
670dffe0da8SDoug MacEachern    int status = sigar_getprocs(sigar, pid);
67192a33c7cSDoug MacEachern    struct procsinfo64 *pinfo = sigar->pinfo;
672dffe0da8SDoug MacEachern
673dffe0da8SDoug MacEachern    if (status != SIGAR_OK) {
674dffe0da8SDoug MacEachern        return status;
675dffe0da8SDoug MacEachern    }
676dffe0da8SDoug MacEachern
677dffe0da8SDoug MacEachern    proctime->start_time = pinfo->pi_start;
678795fa1aeSDoug MacEachern    proctime->start_time *= SIGAR_MSEC; /* convert to ms */
679795fa1aeSDoug MacEachern    proctime->user = pinfo->pi_utime * SIGAR_MSEC;
680795fa1aeSDoug MacEachern    proctime->sys  = pinfo->pi_stime * SIGAR_MSEC;
6814736d77cSDoug MacEachern    proctime->total = proctime->user + proctime->sys;
682dffe0da8SDoug MacEachern
683dffe0da8SDoug MacEachern    return SIGAR_OK;
684dffe0da8SDoug MacEachern}
685dffe0da8SDoug MacEachern
686dffe0da8SDoug MacEachernint sigar_proc_state_get(sigar_t *sigar, sigar_pid_t pid,
687dffe0da8SDoug MacEachern                         sigar_proc_state_t *procstate)
688dffe0da8SDoug MacEachern{
689dffe0da8SDoug MacEachern    int status = sigar_getprocs(sigar, pid);
69092a33c7cSDoug MacEachern    struct procsinfo64 *pinfo = sigar->pinfo;
6916b7a36f5SDoug MacEachern    tid_t tid = 0;
6926b7a36f5SDoug MacEachern    struct thrdsinfo64 thrinfo;
693dffe0da8SDoug MacEachern
694dffe0da8SDoug MacEachern    if (status != SIGAR_OK) {
695dffe0da8SDoug MacEachern        return status;
696dffe0da8SDoug MacEachern    }
697dffe0da8SDoug MacEachern
6986b7a36f5SDoug MacEachern    if (getthrds(pid, &thrinfo, sizeof(thrinfo), &tid, 1) == 1) {
6996b7a36f5SDoug MacEachern        procstate->processor = thrinfo.ti_affinity;
7006b7a36f5SDoug MacEachern    }
7016b7a36f5SDoug MacEachern    else {
7026b7a36f5SDoug MacEachern        procstate->processor = SIGAR_FIELD_NOTIMPL;
7036b7a36f5SDoug MacEachern    }
704829a4c03STrond Norbye
705dffe0da8SDoug MacEachern    SIGAR_SSTRCPY(procstate->name, pinfo->pi_comm);
706dffe0da8SDoug MacEachern    procstate->ppid = pinfo->pi_ppid;
707dffe0da8SDoug MacEachern    procstate->nice = pinfo->pi_nice;
708dffe0da8SDoug MacEachern    procstate->tty  = pinfo->pi_ttyd;
70992a33c7cSDoug MacEachern    procstate->priority = pinfo->pi_pri;
71060271c8aSDoug MacEachern    procstate->threads = pinfo->pi_thcount;
71160271c8aSDoug MacEachern
712dffe0da8SDoug MacEachern    switch (pinfo->pi_state) {
713dffe0da8SDoug MacEachern      case SACTIVE:
714dffe0da8SDoug MacEachern        procstate->state = 'R';
715dffe0da8SDoug MacEachern        break;
716dffe0da8SDoug MacEachern      case SIDL:
717dffe0da8SDoug MacEachern        procstate->state = 'D';
718dffe0da8SDoug MacEachern        break;
719dffe0da8SDoug MacEachern      case SSTOP:
720dffe0da8SDoug MacEachern        procstate->state = 'S';
721dffe0da8SDoug MacEachern        break;
722dffe0da8SDoug MacEachern      case SZOMB:
723dffe0da8SDoug MacEachern        procstate->state = 'Z';
724dffe0da8SDoug MacEachern        break;
725dffe0da8SDoug MacEachern      case SSWAP:
726dffe0da8SDoug MacEachern        procstate->state = 'S';
727dffe0da8SDoug MacEachern        break;
728dffe0da8SDoug MacEachern    }
729dffe0da8SDoug MacEachern
730dffe0da8SDoug MacEachern    return SIGAR_OK;
731dffe0da8SDoug MacEachern}
732dffe0da8SDoug MacEachern
733a0f68ed2SDoug MacEachernstatic int sigar_proc_modules_local_get(sigar_t *sigar,
734a0f68ed2SDoug MacEachern                                        sigar_proc_modules_t *procmods)
735a0f68ed2SDoug MacEachern{
736a0f68ed2SDoug MacEachern    struct ld_info *info;
737a0f68ed2SDoug MacEachern    char *buffer;
738a0f68ed2SDoug MacEachern    int size = 2048, status;
739a0f68ed2SDoug MacEachern    unsigned int offset;
740a0f68ed2SDoug MacEachern
741a0f68ed2SDoug MacEachern    buffer = malloc(size);
742a0f68ed2SDoug MacEachern    while ((loadquery(L_GETINFO, buffer, size) == -1) &&
743a0f68ed2SDoug MacEachern           (errno == ENOMEM))
744a0f68ed2SDoug MacEachern    {
745a0f68ed2SDoug MacEachern        size += 2048;
746a0f68ed2SDoug MacEachern        buffer = realloc(buffer, size);
747a0f68ed2SDoug MacEachern    }
748a0f68ed2SDoug MacEachern
749a0f68ed2SDoug MacEachern    info = (struct ld_info *)buffer;
750a0f68ed2SDoug MacEachern
751a0f68ed2SDoug MacEachern    do {
752a0f68ed2SDoug MacEachern        char *name = info->ldinfo_filename;
753a0f68ed2SDoug MacEachern
754829a4c03STrond Norbye        status =
755a0f68ed2SDoug MacEachern            procmods->module_getter(procmods->data, name, strlen(name));
756a0f68ed2SDoug MacEachern
757a0f68ed2SDoug MacEachern        if (status != SIGAR_OK) {
758a0f68ed2SDoug MacEachern            /* not an error; just stop iterating */
759a0f68ed2SDoug MacEachern            free(buffer);
760a0f68ed2SDoug MacEachern            return status;
761a0f68ed2SDoug MacEachern        }
762829a4c03STrond Norbye
763a0f68ed2SDoug MacEachern        offset = info->ldinfo_next;
764a0f68ed2SDoug MacEachern        info = (struct ld_info *)((char*)info + offset);
765a0f68ed2SDoug MacEachern    } while(offset);
766a0f68ed2SDoug MacEachern
767a0f68ed2SDoug MacEachern    free(buffer);
768a0f68ed2SDoug MacEachern
769a0f68ed2SDoug MacEachern    return SIGAR_OK;
770a0f68ed2SDoug MacEachern}
771a0f68ed2SDoug MacEachern
77297472cb4SDoug MacEachern
773bee745afSDoug MacEachern#define SIGAR_MICROSEC2NANO(s) \
774bee745afSDoug MacEachern    ((sigar_uint64_t)(s) * (sigar_uint64_t)1000)
775bee745afSDoug MacEachern
776bee745afSDoug MacEachern#define TIME_NSEC(t) \
777bee745afSDoug MacEachern    (SIGAR_SEC2NANO((t).tv_sec) + SIGAR_MICROSEC2NANO((t).tv_usec))
778bee745afSDoug MacEachern
7791299660bSDoug MacEachern
780dffe0da8SDoug MacEachernint sigar_os_fs_type_get(sigar_file_system_t *fsp)
781dffe0da8SDoug MacEachern{
782dffe0da8SDoug MacEachern    return fsp->type;
783dffe0da8SDoug MacEachern}
784dffe0da8SDoug MacEachern
7854d444023SDoug MacEachern#ifndef MNT_NFS4
786dffe0da8SDoug MacEachern/* another one documented in aix tech ref
7874d444023SDoug MacEachern * with no friggin prototype in any header file...
7884d444023SDoug MacEachern * ...but added in 5.2
789dffe0da8SDoug MacEachern */
790dffe0da8SDoug MacEachernint mntctl(int command, int size, char *buffer);
7914d444023SDoug MacEachern#endif
792dffe0da8SDoug MacEachern
793dffe0da8SDoug MacEachernint sigar_file_system_list_get(sigar_t *sigar,
794dffe0da8SDoug MacEachern                               sigar_file_system_list_t *fslist)
795dffe0da8SDoug MacEachern{
796dffe0da8SDoug MacEachern    int i, size, num;
797dffe0da8SDoug MacEachern    char *buf, *mntlist;
798dffe0da8SDoug MacEachern
799dffe0da8SDoug MacEachern    /* get required size */
800dffe0da8SDoug MacEachern    if (mntctl(MCTL_QUERY, sizeof(size), (char *)&size) < 0) {
801dffe0da8SDoug MacEachern        return errno;
802dffe0da8SDoug MacEachern    }
803dffe0da8SDoug MacEachern
804dffe0da8SDoug MacEachern    mntlist = buf = malloc(size);
805dffe0da8SDoug MacEachern
806dffe0da8SDoug MacEachern    if ((num = mntctl(MCTL_QUERY, size, buf)) < 0) {
807dffe0da8SDoug MacEachern        free(buf);
808dffe0da8SDoug MacEachern        return errno;
809dffe0da8SDoug MacEachern    }
810dffe0da8SDoug MacEachern
811dffe0da8SDoug MacEachern    sigar_file_system_list_create(fslist);
812dffe0da8SDoug MacEachern
813dffe0da8SDoug MacEachern    for (i=0; i<num; i++) {
814dffe0da8SDoug MacEachern        char *devname;
815dffe0da8SDoug MacEachern        const char *typename = NULL;
816dffe0da8SDoug MacEachern        sigar_file_system_t *fsp;
817dffe0da8SDoug MacEachern        struct vmount *ent = (struct vmount *)mntlist;
818dffe0da8SDoug MacEachern
819dffe0da8SDoug MacEachern        mntlist += ent->vmt_length;
820dffe0da8SDoug MacEachern
821dffe0da8SDoug MacEachern        SIGAR_FILE_SYSTEM_LIST_GROW(fslist);
822dffe0da8SDoug MacEachern
823dffe0da8SDoug MacEachern        fsp = &fslist->data[fslist->number++];
824dffe0da8SDoug MacEachern
825dffe0da8SDoug MacEachern        switch (ent->vmt_gfstype) {
826dffe0da8SDoug MacEachern          case MNT_AIX:
827dffe0da8SDoug MacEachern            typename = "aix";
828dffe0da8SDoug MacEachern            fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
829dffe0da8SDoug MacEachern            break;
830dffe0da8SDoug MacEachern          case MNT_JFS:
831dffe0da8SDoug MacEachern            typename = "jfs";
832dffe0da8SDoug MacEachern            fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
833dffe0da8SDoug MacEachern            break;
834dffe0da8SDoug MacEachern          case MNT_NFS:
835dffe0da8SDoug MacEachern          case MNT_NFS3:
836dffe0da8SDoug MacEachern            typename = "nfs";
837dffe0da8SDoug MacEachern            fsp->type = SIGAR_FSTYPE_NETWORK;
838dffe0da8SDoug MacEachern            break;
839dffe0da8SDoug MacEachern          case MNT_CDROM:
840dffe0da8SDoug MacEachern            fsp->type = SIGAR_FSTYPE_CDROM;
841dffe0da8SDoug MacEachern            break;
842dffe0da8SDoug MacEachern          case MNT_SFS:
843dffe0da8SDoug MacEachern          case MNT_CACHEFS:
844dffe0da8SDoug MacEachern          case MNT_AUTOFS:
845dffe0da8SDoug MacEachern          default:
846dffe0da8SDoug MacEachern            if (ent->vmt_flags & MNT_REMOTE) {
847dffe0da8SDoug MacEachern                fsp->type = SIGAR_FSTYPE_NETWORK;
848dffe0da8SDoug MacEachern            }
849dffe0da8SDoug MacEachern            else {
850dffe0da8SDoug MacEachern                fsp->type = SIGAR_FSTYPE_NONE;
851dffe0da8SDoug MacEachern            }
852dffe0da8SDoug MacEachern        }
853dffe0da8SDoug MacEachern
854dffe0da8SDoug MacEachern        SIGAR_SSTRCPY(fsp->dir_name, vmt2dataptr(ent, VMT_STUB));
85522c7c42aSDoug MacEachern        SIGAR_SSTRCPY(fsp->options, vmt2dataptr(ent, VMT_ARGS));
856829a4c03STrond Norbye
857dffe0da8SDoug MacEachern        devname = vmt2dataptr(ent, VMT_OBJECT);
858dffe0da8SDoug MacEachern
859dffe0da8SDoug MacEachern        if (fsp->type == SIGAR_FSTYPE_NETWORK) {
860dffe0da8SDoug MacEachern            char *hostname   = vmt2dataptr(ent, VMT_HOSTNAME);
861dffe0da8SDoug MacEachern#if 0
862dffe0da8SDoug MacEachern            /* XXX: these do not seem reliable */
863dffe0da8SDoug MacEachern            int hostname_len = vmt2datasize(ent, VMT_HOSTNAME)-1; /* -1 == skip '\0' */
864dffe0da8SDoug MacEachern            int devname_len  = vmt2datasize(ent, VMT_OBJECT);     /* includes '\0' */
865dffe0da8SDoug MacEachern#else
866dffe0da8SDoug MacEachern            int hostname_len = strlen(hostname);
867dffe0da8SDoug MacEachern            int devname_len = strlen(devname) + 1;
868dffe0da8SDoug MacEachern#endif
869dffe0da8SDoug MacEachern            int total_len    = hostname_len + devname_len + 1;    /* 1 == strlen(":") */
870dffe0da8SDoug MacEachern
871dffe0da8SDoug MacEachern            if (total_len > sizeof(fsp->dev_name)) {
872dffe0da8SDoug MacEachern                /* justincase - prevent overflow.  chances: slim..none */
873dffe0da8SDoug MacEachern                SIGAR_SSTRCPY(fsp->dev_name, devname);
874dffe0da8SDoug MacEachern            }
875dffe0da8SDoug MacEachern            else {
876dffe0da8SDoug MacEachern                /* sprintf(fsp->devname, "%s:%s", hostname, devname) */
877dffe0da8SDoug MacEachern                char *ptr = fsp->dev_name;
878dffe0da8SDoug MacEachern
879dffe0da8SDoug MacEachern                memcpy(ptr, hostname, hostname_len);
880dffe0da8SDoug MacEachern                ptr += hostname_len;
881dffe0da8SDoug MacEachern
882dffe0da8SDoug MacEachern                *ptr++ = ':';
883dffe0da8SDoug MacEachern
884dffe0da8SDoug MacEachern                memcpy(ptr, devname, devname_len);
885dffe0da8SDoug MacEachern            }
886dffe0da8SDoug MacEachern        }
887dffe0da8SDoug MacEachern        else {
888dffe0da8SDoug MacEachern            SIGAR_SSTRCPY(fsp->dev_name, devname);
889dffe0da8SDoug MacEachern        }
890dffe0da8SDoug MacEachern
891dffe0da8SDoug MacEachern        /* we set fsp->type, just looking up sigar.c:fstype_names[type] */
892dffe0da8SDoug MacEachern        sigar_fs_type_get(fsp);
893dffe0da8SDoug MacEachern
894dffe0da8SDoug MacEachern        if (typename == NULL) {
895dffe0da8SDoug MacEachern            typename = fsp->type_name;
896dffe0da8SDoug MacEachern        }
897dffe0da8SDoug MacEachern
898dffe0da8SDoug MacEachern        SIGAR_SSTRCPY(fsp->sys_type_name, typename);
899dffe0da8SDoug MacEachern    }
900dffe0da8SDoug MacEachern
901dffe0da8SDoug MacEachern    free(buf);
902dffe0da8SDoug MacEachern
903dffe0da8SDoug MacEachern    return SIGAR_OK;
904dffe0da8SDoug MacEachern}
905dffe0da8SDoug MacEachern
9063cd8cf76SDoug MacEacherntypedef struct {
9077239440bSDoug MacEachern    char name[IDENTIFIER_LENGTH];
9083cd8cf76SDoug MacEachern    long addr;
9093cd8cf76SDoug MacEachern} aix_diskio_t;
9103cd8cf76SDoug MacEachern
9114c587388SDoug MacEachernstatic int create_diskmap(sigar_t *sigar)
91261664d00SDoug MacEachern{
91361664d00SDoug MacEachern    int i, total, num;
91461664d00SDoug MacEachern    perfstat_disk_t *disk;
91561664d00SDoug MacEachern    perfstat_id_t id;
91661664d00SDoug MacEachern
9174c587388SDoug MacEachern    total = perfstat_disk(NULL, NULL, sizeof(*disk), 0);
91861664d00SDoug MacEachern    if (total < 1) {
91961664d00SDoug MacEachern        return ENOENT;
92061664d00SDoug MacEachern    }
92161664d00SDoug MacEachern
92261664d00SDoug MacEachern    disk = malloc(total * sizeof(*disk));
92361664d00SDoug MacEachern    id.name[0] = '\0';
92461664d00SDoug MacEachern
9254c587388SDoug MacEachern    num = perfstat_disk(&id, disk, sizeof(*disk), total);
92661664d00SDoug MacEachern    if (num < 1) {
92761664d00SDoug MacEachern        free(disk);
92861664d00SDoug MacEachern        return ENOENT;
92961664d00SDoug MacEachern    }
93061664d00SDoug MacEachern
93161664d00SDoug MacEachern    sigar->diskmap = sigar_cache_new(25);
93261664d00SDoug MacEachern
93361664d00SDoug MacEachern    odm_initialize();
93461664d00SDoug MacEachern
93561664d00SDoug MacEachern    for (i=0; i<num; i++) {
93661664d00SDoug MacEachern        char query[256];
93761664d00SDoug MacEachern        struct CuDv *dv, *ptr;
93861664d00SDoug MacEachern        struct listinfo info;
93961664d00SDoug MacEachern        sigar_cache_entry_t *ent;
94061664d00SDoug MacEachern        int j;
94161664d00SDoug MacEachern
942f32e386bSDoug MacEachern        snprintf(query, sizeof(query),
943f32e386bSDoug MacEachern                 "parent = '%s'", disk[i].vgname);
94461664d00SDoug MacEachern
94561664d00SDoug MacEachern        ptr = dv = odm_get_list(CuDv_CLASS, query, &info, 256, 1);
94661664d00SDoug MacEachern        if ((int)dv == -1) {
94761664d00SDoug MacEachern            continue; /* XXX */
94861664d00SDoug MacEachern        }
94961664d00SDoug MacEachern
95061664d00SDoug MacEachern        for (j=0; j<info.num; j++, ptr++) {
95161664d00SDoug MacEachern            struct CuAt *attr;
95261664d00SDoug MacEachern            int num, retval;
95361664d00SDoug MacEachern            struct stat sb;
95461664d00SDoug MacEachern
95561664d00SDoug MacEachern            if ((attr = getattr(ptr->name, "label", 0, &num))) {
95661664d00SDoug MacEachern                retval = stat(attr->value, &sb);
95761664d00SDoug MacEachern
95861664d00SDoug MacEachern                if (retval == 0) {
95961664d00SDoug MacEachern                    aix_diskio_t *diskio = malloc(sizeof(*diskio));
9607239440bSDoug MacEachern                    SIGAR_SSTRCPY(diskio->name, disk[i].name);
96161664d00SDoug MacEachern                    diskio->addr = -1;
96298157a49SDoug MacEachern                    ent = sigar_cache_get(sigar->diskmap, SIGAR_FSDEV_ID(sb));
96361664d00SDoug MacEachern                    ent->value = diskio;
96461664d00SDoug MacEachern                }
96561664d00SDoug MacEachern
96661664d00SDoug MacEachern                free(attr);
96761664d00SDoug MacEachern            }
96861664d00SDoug MacEachern        }
96961664d00SDoug MacEachern
97061664d00SDoug MacEachern        odm_free_list(dv, &info);
97161664d00SDoug MacEachern    }
97261664d00SDoug MacEachern
97361664d00SDoug MacEachern    free(disk);
97461664d00SDoug MacEachern    odm_terminate();
97561664d00SDoug MacEachern
97661664d00SDoug MacEachern    return SIGAR_OK;
97761664d00SDoug MacEachern}
97861664d00SDoug MacEachern
979dffe0da8SDoug MacEachern
9808a9bb2b7SDoug MacEachern/* from sys/systemcfg.h, not defined in 4.3 headers */
9818a9bb2b7SDoug MacEachern#ifndef POWER_4
9828a9bb2b7SDoug MacEachern#define POWER_4		0x0800
9838a9bb2b7SDoug MacEachern#endif
9848a9bb2b7SDoug MacEachern#ifndef POWER_MPC7450
9858a9bb2b7SDoug MacEachern#define POWER_MPC7450	0x1000
9868a9bb2b7SDoug MacEachern#endif
987ad495656SDoug MacEachern#ifndef POWER_5
9888a9bb2b7SDoug MacEachern#define POWER_5		0x2000
9898a9bb2b7SDoug MacEachern#endif
9908a9bb2b7SDoug MacEachern
9913575b131SDoug MacEachernstatic char *sigar_get_odm_model(sigar_t *sigar)
9923575b131SDoug MacEachern{
9933575b131SDoug MacEachern    if (sigar->model[0] == '\0') {
9943575b131SDoug MacEachern        struct CuAt *odm_obj;
9953575b131SDoug MacEachern        int num;
9963575b131SDoug MacEachern
9973575b131SDoug MacEachern        odm_initialize();
9983575b131SDoug MacEachern
9993575b131SDoug MacEachern        if ((odm_obj = getattr("proc0", "type", 0, &num))) {
10003575b131SDoug MacEachern            SIGAR_SSTRCPY(sigar->model, odm_obj->value);
10013575b131SDoug MacEachern            free(odm_obj);
10023575b131SDoug MacEachern        }
10033575b131SDoug MacEachern
10043575b131SDoug MacEachern        odm_terminate();
10053575b131SDoug MacEachern    }
10063575b131SDoug MacEachern
10073575b131SDoug MacEachern    return sigar->model;
10083575b131SDoug MacEachern}
10093575b131SDoug MacEachern
10109a00bf0cSDoug MacEachern#define SIGAR_CPU_CACHE_SIZE \
10119a00bf0cSDoug MacEachern  (_system_configuration.L2_cache_size / 1024)
10129a00bf0cSDoug MacEachern
10134c587388SDoug MacEachernstatic int sigar_get_cpu_mhz(sigar_t *sigar)
10149a00bf0cSDoug MacEachern{
10154c587388SDoug MacEachern    if (sigar->cpu_mhz == SIGAR_FIELD_NOTIMPL) {
10164c587388SDoug MacEachern        perfstat_cpu_total_t data;
10179a00bf0cSDoug MacEachern
10184c587388SDoug MacEachern        if (sigar_perfstat_cpu(&data) == 1) {
10197d6f84e8SDoug MacEachern            sigar->cpu_mhz = data.processorHZ / 1000000;
1020ef21ab23SDoug MacEachern        }
10211df568b4SDoug MacEachern        else {
10221df568b4SDoug MacEachern            sigar_log_printf(sigar, SIGAR_LOG_ERROR,
10231df568b4SDoug MacEachern                             "perfstat_cpu_total failed: %s",
10241df568b4SDoug MacEachern                             sigar_strerror(sigar, errno));
10251df568b4SDoug MacEachern        }
10269a00bf0cSDoug MacEachern    }
10279a00bf0cSDoug MacEachern
10289a00bf0cSDoug MacEachern    return sigar->cpu_mhz;
10299a00bf0cSDoug MacEachern}
10309a00bf0cSDoug MacEachern
1031f5e87e75SDoug MacEachernstatic char *get_cpu_arch(void)
1032f5e87e75SDoug MacEachern{
1033f5e87e75SDoug MacEachern    switch (_system_configuration.architecture) {
1034f5e87e75SDoug MacEachern        case POWER_RS:
1035f5e87e75SDoug MacEachern            return "Power Classic";
1036f5e87e75SDoug MacEachern        case POWER_PC:
1037f5e87e75SDoug MacEachern            return "PowerPC";
1038f5e87e75SDoug MacEachern        case IA64:
1039f5e87e75SDoug MacEachern            return "IA64";
1040f5e87e75SDoug MacEachern        default:
1041f5e87e75SDoug MacEachern            return "PowerPC"; /* what else could it be */
1042f5e87e75SDoug MacEachern    }
1043f5e87e75SDoug MacEachern}
1044f5e87e75SDoug MacEachern
104535ed4a62SDoug MacEachernstatic char *get_ppc_cpu_model(void)
104635ed4a62SDoug MacEachern{
104735ed4a62SDoug MacEachern    switch (_system_configuration.implementation) {
104835ed4a62SDoug MacEachern        case POWER_RS1:
104935ed4a62SDoug MacEachern            return "RS1";
105035ed4a62SDoug MacEachern        case POWER_RSC:
105135ed4a62SDoug MacEachern            return "RSC";
105235ed4a62SDoug MacEachern        case POWER_RS2:
105335ed4a62SDoug MacEachern            return "RS2";
105435ed4a62SDoug MacEachern        case POWER_601:
105535ed4a62SDoug MacEachern            return "601";
105635ed4a62SDoug MacEachern        case POWER_603:
105735ed4a62SDoug MacEachern            return "603";
105835ed4a62SDoug MacEachern        case POWER_604:
105935ed4a62SDoug MacEachern            return "604";
106035ed4a62SDoug MacEachern        case POWER_620:
106135ed4a62SDoug MacEachern            return "620";
106235ed4a62SDoug MacEachern        case POWER_630:
106335ed4a62SDoug MacEachern            return "630";
106435ed4a62SDoug MacEachern        case POWER_A35:
106535ed4a62SDoug MacEachern            return "A35";
106635ed4a62SDoug MacEachern        case POWER_RS64II:
106735ed4a62SDoug MacEachern            return "RS64-II";
106835ed4a62SDoug MacEachern        case POWER_RS64III:
106935ed4a62SDoug MacEachern            return "RS64-III";
107035ed4a62SDoug MacEachern        case POWER_4:
107135ed4a62SDoug MacEachern            return "POWER4";
107235ed4a62SDoug MacEachern        case POWER_MPC7450:
107335ed4a62SDoug MacEachern            return "MPC7450";
107435ed4a62SDoug MacEachern        case POWER_5:
107535ed4a62SDoug MacEachern            return "POWER5";
107635ed4a62SDoug MacEachern        default:
107735ed4a62SDoug MacEachern            return "Unknown";
107835ed4a62SDoug MacEachern    }
107935ed4a62SDoug MacEachern}
108035ed4a62SDoug MacEachern
108135ed4a62SDoug MacEachernstatic char *get_ia64_cpu_model(void)
108235ed4a62SDoug MacEachern{
108335ed4a62SDoug MacEachern    switch (_system_configuration.implementation) {
108435ed4a62SDoug MacEachern        case IA64_M1:
108535ed4a62SDoug MacEachern            return "M1";
108635ed4a62SDoug MacEachern        case IA64_M2:
108735ed4a62SDoug MacEachern            return "M2";
108835ed4a62SDoug MacEachern        default:
108935ed4a62SDoug MacEachern            return "Unknown";
109035ed4a62SDoug MacEachern    }
109135ed4a62SDoug MacEachern}
109235ed4a62SDoug MacEachern
109335ed4a62SDoug MacEachernstatic char *get_cpu_model(void)
109435ed4a62SDoug MacEachern{
109535ed4a62SDoug MacEachern    if (_system_configuration.architecture == IA64) {
109635ed4a62SDoug MacEachern        return get_ia64_cpu_model();
109735ed4a62SDoug MacEachern    }
109835ed4a62SDoug MacEachern    else {
109935ed4a62SDoug MacEachern        return get_ppc_cpu_model();
110035ed4a62SDoug MacEachern    }
110135ed4a62SDoug MacEachern}
110235ed4a62SDoug MacEachern
110339fef6c3SDoug MacEachern/* XXX net_route_list copy-n-pasted from darwin_sigar.c; only diff is getkerninfo instead of sysctl */
110439fef6c3SDoug MacEachern#define rt_s_addr(sa) ((struct sockaddr_in *)(sa))->sin_addr.s_addr
110539fef6c3SDoug MacEachern
110639fef6c3SDoug MacEachern#ifndef SA_SIZE
110739fef6c3SDoug MacEachern#define SA_SIZE(sa)                                             \
110839fef6c3SDoug MacEachern    (  (!(sa) || ((struct sockaddr *)(sa))->sa_len == 0) ?      \
110939fef6c3SDoug MacEachern        sizeof(long)            :                               \
111039fef6c3SDoug MacEachern        1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(long) - 1) ) )
111139fef6c3SDoug MacEachern#endif
1112dffe0da8SDoug MacEachern
1113ea4f9c7eSDoug MacEachern
11140e763c13SDoug MacEachernint sigar_net_interface_ipv6_config_get(sigar_t *sigar, const char *name,
11150e763c13SDoug MacEachern                                        sigar_net_interface_config_t *ifconfig)
11160e763c13SDoug MacEachern{
1117e92da524SDoug MacEachern    int sock;
1118e92da524SDoug MacEachern    struct in6_ifreq ifr;
1119e92da524SDoug MacEachern
1120e92da524SDoug MacEachern    if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
1121e92da524SDoug MacEachern        return errno;
1122e92da524SDoug MacEachern    }
1123e92da524SDoug MacEachern
1124e92da524SDoug MacEachern    SIGAR_SSTRCPY(ifr.ifr_name, name);
1125e92da524SDoug MacEachern
1126e92da524SDoug MacEachern    if (ioctl(sock, SIOCGIFADDR6, &ifr) == 0) {
1127e92da524SDoug MacEachern        struct in6_addr *addr = SIGAR_SIN6_ADDR(&ifr.ifr_Addr);
1128e92da524SDoug MacEachern
1129e92da524SDoug MacEachern        sigar_net_address6_set(ifconfig->address6, addr);
1130e92da524SDoug MacEachern        sigar_net_interface_scope6_set(ifconfig, addr);
1131e92da524SDoug MacEachern
1132e92da524SDoug MacEachern        if (ioctl(sock, SIOCGIFNETMASK6, &ifr) == 0) {
1133e92da524SDoug MacEachern            addr = SIGAR_SIN6_ADDR(&ifr.ifr_Addr);
1134e92da524SDoug MacEachern            ifconfig->prefix6_length = SIGAR_SIN6(&ifr.ifr_Addr)->sin6_len; /*XXX*/
1135e92da524SDoug MacEachern        }
1136e92da524SDoug MacEachern    }
1137e92da524SDoug MacEachern
1138e92da524SDoug MacEachern    close(sock);
1139e92da524SDoug MacEachern    return SIGAR_OK;
11400e763c13SDoug MacEachern}
11410e763c13SDoug MacEachern
1142b1815c1dSDoug MacEachern#define IS_TCP_SERVER(state, flags) \
1143b1815c1dSDoug MacEachern    ((flags & SIGAR_NETCONN_SERVER) && (state == TCPS_LISTEN))
1144b1815c1dSDoug MacEachern
1145b1815c1dSDoug MacEachern#define IS_TCP_CLIENT(state, flags) \
1146b1815c1dSDoug MacEachern    ((flags & SIGAR_NETCONN_CLIENT) && (state != TCPS_LISTEN))
1147b1815c1dS