diff options
Diffstat (limited to 'psutil/arch/openbsd/socks.c')
-rw-r--r-- | psutil/arch/openbsd/socks.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/psutil/arch/openbsd/socks.c b/psutil/arch/openbsd/socks.c new file mode 100644 index 00000000..69daa447 --- /dev/null +++ b/psutil/arch/openbsd/socks.c @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2009, Giampaolo Rodola'. + * All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include <Python.h> +#include <sys/sysctl.h> +#include <sys/socket.h> +#include <kvm.h> +#define _KERNEL // silence compiler warning +#include <sys/file.h> // DTYPE_SOCKET +#include <netdb.h> // INET6_ADDRSTRLEN, in6_addr +#undef _KERNEL + +#include "../../_psutil_common.h" +#include "../../_psutil_posix.h" + + +PyObject * +psutil_net_connections(PyObject *self, PyObject *args) { + pid_t pid; + int i; + int cnt; + int state; + int lport; + int rport; + char lip[INET6_ADDRSTRLEN]; + char rip[INET6_ADDRSTRLEN]; + int inseq; + + char errbuf[_POSIX2_LINE_MAX]; + kvm_t *kd = NULL; + + struct kinfo_file *kif; + struct kinfo_file *ikf; + struct in6_addr laddr6; + + PyObject *py_retlist = PyList_New(0); + PyObject *py_tuple = NULL; + PyObject *py_laddr = NULL; + PyObject *py_raddr = NULL; + PyObject *py_lpath = NULL; + PyObject *py_af_filter = NULL; + PyObject *py_type_filter = NULL; + PyObject *py_family = NULL; + PyObject *_type = NULL; + + + if (py_retlist == NULL) + return NULL; + if (! PyArg_ParseTuple(args, _Py_PARSE_PID "OO", &pid, &py_af_filter, + &py_type_filter)) { + goto error; + } + if (!PySequence_Check(py_af_filter) || !PySequence_Check(py_type_filter)) { + PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence"); + goto error; + } + + kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + if (! kd) { + convert_kvm_err("kvm_openfiles", errbuf); + goto error; + } + + ikf = kvm_getfiles(kd, KERN_FILE_BYPID, -1, sizeof(*ikf), &cnt); + if (! ikf) { + PyErr_SetFromOSErrnoWithSyscall("kvm_getfiles"); + goto error; + } + + for (int i = 0; i < cnt; i++) { + const struct kinfo_file *kif = ikf + i; + py_tuple = NULL; + py_laddr = NULL; + py_raddr = NULL; + py_lpath = NULL; + + // apply filters + if (kif->f_type != DTYPE_SOCKET) + continue; + if (pid != -1 && kif->p_pid != (uint32_t)pid) + continue; + py_family = PyLong_FromLong((long)kif->so_family); + inseq = PySequence_Contains(py_af_filter, py_family); + Py_DECREF(py_family); + if (inseq == 0) + continue; + _type = PyLong_FromLong((long)kif->so_type); + inseq = PySequence_Contains(py_type_filter, _type); + Py_DECREF(_type); + if (inseq == 0) + continue; + + // IPv4 / IPv6 socket + if ((kif->so_family == AF_INET) || (kif->so_family == AF_INET6)) { + // status + if (kif->so_type == SOCK_STREAM) + state = kif->t_state; + else + state = PSUTIL_CONN_NONE; + + // local & remote port + lport = ntohs(kif->inp_lport); + rport = ntohs(kif->inp_fport); + + // local addr + inet_ntop(kif->so_family, &kif->inp_laddru, lip, sizeof(lip)); + py_laddr = Py_BuildValue("(si)", lip, lport); + if (! py_laddr) + goto error; + + // remote addr + if (rport != 0) { + inet_ntop(kif->so_family, &kif->inp_faddru, rip, sizeof(rip)); + py_raddr = Py_BuildValue("(si)", rip, rport); + } + else { + py_raddr = Py_BuildValue("()"); + } + if (! py_raddr) + goto error; + + // populate tuple and list + py_tuple = Py_BuildValue( + "(iiiNNil)", + kif->fd_fd, + kif->so_family, + kif->so_type, + py_laddr, + py_raddr, + state, + kif->p_pid + ); + if (! py_tuple) + goto error; + if (PyList_Append(py_retlist, py_tuple)) + goto error; + Py_DECREF(py_tuple); + } + // UNIX socket + else if (kif->so_family == AF_UNIX) { + py_lpath = PyUnicode_DecodeFSDefault(kif->unp_path); + if (! py_lpath) + goto error; + + py_tuple = Py_BuildValue( + "(iiiOsil)", + kif->fd_fd, + kif->so_family, + kif->so_type, + py_lpath, + "", // raddr + PSUTIL_CONN_NONE, + kif->p_pid + ); + if (! py_tuple) + goto error; + if (PyList_Append(py_retlist, py_tuple)) + goto error; + Py_DECREF(py_lpath); + Py_DECREF(py_tuple); + Py_INCREF(Py_None); + } + } + + kvm_close(kd); + return py_retlist; + +error: + Py_XDECREF(py_tuple); + Py_XDECREF(py_laddr); + Py_XDECREF(py_raddr); + Py_DECREF(py_retlist); + if (kd != NULL) + kvm_close(kd); + return NULL; +} |