PyObject * psutil_proc_num_fds(PyObject *self, PyObject *args) { long pid; int cnt; struct kinfo_file *freep; if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; errno = 0; freep = kinfo_getfile(pid, &cnt); if (freep == NULL) { psutil_raise_for_pid(pid, "kinfo_getfile()"); return NULL; } free(freep); return Py_BuildValue("i", cnt); }
static struct xtcpcb * psutil_search_tcplist(char *buf, struct kinfo_file *kif) { struct xtcpcb *tp; struct xinpcb *inp; #else static struct tcpcb * psutil_search_tcplist(char *buf, struct kinfo_file *kif) { struct tcpcb *tp; struct inpcb *inp; #endif struct xinpgen *xig, *oxig; struct xsocket *so; oxig = xig = (struct xinpgen *)buf; for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); xig->xig_len > sizeof(struct xinpgen); xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { #if __FreeBSD_version >= 1200026 tp = (struct xtcpcb *)xig; inp = &tp->xt_inp; so = &inp->xi_socket; #else tp = &((struct xtcpcb *)xig)->xt_tp; inp = &((struct xtcpcb *)xig)->xt_inp; so = &((struct xtcpcb *)xig)->xt_socket; #endif if (so->so_type != kif->kf_sock_type || so->xso_family != kif->kf_sock_domain || so->xso_protocol != kif->kf_sock_protocol) continue; if (kif->kf_sock_domain == AF_INET) { if (!psutil_sockaddr_matches( AF_INET, inp->inp_lport, &inp->inp_laddr, &kif->kf_sa_local)) continue; if (!psutil_sockaddr_matches( AF_INET, inp->inp_fport, &inp->inp_faddr, &kif->kf_sa_peer)) continue; } else { if (!psutil_sockaddr_matches( AF_INET6, inp->inp_lport, &inp->in6p_laddr, &kif->kf_sa_local)) continue; if (!psutil_sockaddr_matches( AF_INET6, inp->inp_fport, &inp->in6p_faddr, &kif->kf_sa_peer)) continue; } return (tp); } return NULL; } PyObject * psutil_proc_connections(PyObject *self, PyObject *args) { // Return connections opened by process. long pid; int i; int cnt; struct kinfo_file *freep = NULL; struct kinfo_file *kif; char *tcplist = NULL; #if __FreeBSD_version >= 1200026 struct xtcpcb *tcp; #else struct tcpcb *tcp; #endif PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; PyObject *py_laddr = NULL; PyObject *py_raddr = NULL; PyObject *py_af_filter = NULL; PyObject *py_type_filter = NULL; PyObject *py_family = NULL; PyObject *py_type = NULL; if (py_retlist == NULL) return NULL; if (! PyArg_ParseTuple(args, "lOO", &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; } errno = 0; freep = kinfo_getfile(pid, &cnt); if (freep == NULL) { psutil_raise_for_pid(pid, "kinfo_getfile() failed"); goto error; } tcplist = psutil_fetch_tcplist(); if (tcplist == NULL) { PyErr_SetFromErrno(PyExc_OSError); goto error; } for (i = 0; i < cnt; i++) { int lport, rport, state; char lip[200], rip[200]; char path[PATH_MAX]; int inseq; py_tuple = NULL; py_laddr = NULL; py_raddr = NULL; kif = &freep[i]; if (kif->kf_type == KF_TYPE_SOCKET) { // apply filters py_family = PyLong_FromLong((long)kif->kf_sock_domain); inseq = PySequence_Contains(py_af_filter, py_family); Py_DECREF(py_family); if (inseq == 0) continue; py_type = PyLong_FromLong((long)kif->kf_sock_type); inseq = PySequence_Contains(py_type_filter, py_type); Py_DECREF(py_type); if (inseq == 0) continue; // IPv4 / IPv6 socket if ((kif->kf_sock_domain == AF_INET) || (kif->kf_sock_domain == AF_INET6)) { // fill status state = PSUTIL_CONN_NONE; if (kif->kf_sock_type == SOCK_STREAM) { tcp = psutil_search_tcplist(tcplist, kif); if (tcp != NULL) state = (int)tcp->t_state; } // build addr and port inet_ntop( kif->kf_sock_domain, psutil_sockaddr_addr(kif->kf_sock_domain, &kif->kf_sa_local), lip, sizeof(lip)); inet_ntop( kif->kf_sock_domain, psutil_sockaddr_addr(kif->kf_sock_domain, &kif->kf_sa_peer), rip, sizeof(rip)); lport = htons(psutil_sockaddr_port(kif->kf_sock_domain, &kif->kf_sa_local)); rport = htons(psutil_sockaddr_port(kif->kf_sock_domain, &kif->kf_sa_peer)); // construct python tuple/list py_laddr = Py_BuildValue("(si)", lip, lport); if (!py_laddr) goto error; if (rport != 0) py_raddr = Py_BuildValue("(si)", rip, rport); else py_raddr = Py_BuildValue("()"); if (!py_raddr) goto error; py_tuple = Py_BuildValue( "(iiiNNi)", kif->kf_fd, kif->kf_sock_domain, kif->kf_sock_type, py_laddr, py_raddr, state ); if (!py_tuple) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_tuple); } // UNIX socket. // Note: remote path cannot be determined. else if (kif->kf_sock_domain == AF_UNIX) { struct sockaddr_un *sun; sun = (struct sockaddr_un *)&kif->kf_sa_local; snprintf( path, sizeof(path), "%.*s", (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))), sun->sun_path); py_laddr = PyUnicode_DecodeFSDefault(path); if (! py_laddr) goto error; py_tuple = Py_BuildValue( "(iiiOsi)", kif->kf_fd, kif->kf_sock_domain, kif->kf_sock_type, py_laddr, "", // raddr can't be determined PSUTIL_CONN_NONE ); if (!py_tuple) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_tuple); Py_DECREF(py_laddr); } } } free(freep); free(tcplist); return py_retlist; error: Py_XDECREF(py_tuple); Py_XDECREF(py_laddr); Py_XDECREF(py_raddr); Py_DECREF(py_retlist); if (freep != NULL) free(freep); if (tcplist != NULL) free(tcplist); return NULL; }