diff --git a/python-inet_diag/inet_diag.c b/python-inet_diag/inet_diag.c
index 26b92ae..33dd8a3 100644
--- a/python-inet_diag/inet_diag.c
+++ b/python-inet_diag/inet_diag.c
@@ -26,6 +26,17 @@
 #include <arpa/inet.h>
 #include <netinet/tcp.h>
 #include <linux/inet_diag.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <netdb.h>
+#include <dirent.h>
+#include <fnmatch.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
 #include "diag_filter.h"
 #ifndef __unused
 #define __unused __attribute__ ((unused))
@@ -136,6 +147,157 @@ static int inet_socket__print(struct inet_socket *self, FILE *fp,
 	return 0;
 }
 
+/* process and user lookup */
+struct user_ent {
+    struct user_ent *next;
+    unsigned int    ino;
+    int     pid;
+    int     fd;
+    char        process[0];
+};
+
+#define USER_ENT_HASH_SIZE  256
+struct user_ent *user_ent_hash[USER_ENT_HASH_SIZE];
+
+int show_users = 0;
+
+static int user_ent_hashfn(unsigned int ino)
+{
+    int val = (ino >> 24) ^ (ino >> 16) ^ (ino >> 8) ^ ino;
+
+    return val & (USER_ENT_HASH_SIZE - 1);
+}
+
+static void user_ent_add(unsigned int ino, const char *process, int pid, int fd)
+{
+    struct user_ent *p, **pp;
+    int str_len;
+
+    str_len = strlen(process) + 1;
+    p = malloc(sizeof(struct user_ent) + str_len);
+    if (!p)
+        abort();
+    p->next = NULL;
+    p->ino = ino;
+    p->pid = pid;
+    p->fd = fd;
+    strcpy(p->process, process);
+
+    pp = &user_ent_hash[user_ent_hashfn(ino)];
+    p->next = *pp;
+    *pp = p;
+}
+
+static void user_ent_hash_build(void)
+{   
+    const char *root = getenv("PROC_ROOT") ? : "/proc/";
+    struct dirent *d;
+    char name[1024];
+    int nameoff;
+    DIR *dir;
+
+    strcpy(name, root);
+    if (strlen(name) == 0 || name[strlen(name)-1] != '/')
+        strcat(name, "/");
+
+    nameoff = strlen(name);
+
+    dir = opendir(name);
+    if (!dir)
+        return;
+
+    while ((d = readdir(dir)) != NULL) {
+        struct dirent *d1;
+        char process[16];
+        int pid, pos;
+        DIR *dir1;
+        char crap;
+
+        if (sscanf(d->d_name, "%d%c", &pid, &crap) != 1)
+            continue;
+
+        sprintf(name + nameoff, "%d/fd/", pid);
+        pos = strlen(name);
+        if ((dir1 = opendir(name)) == NULL)
+            continue;
+
+        process[0] = '\0';
+
+        while ((d1 = readdir(dir1)) != NULL) {
+            const char *pattern = "socket:[";
+            unsigned int ino;
+            char lnk[64];
+            int fd;
+            ssize_t link_len;
+
+            if (sscanf(d1->d_name, "%d%c", &fd, &crap) != 1)
+                continue;
+
+            sprintf(name+pos, "%d", fd);
+
+            link_len = readlink(name, lnk, sizeof(lnk)-1);
+            if (link_len == -1)
+                continue;
+            lnk[link_len] = '\0';
+
+            if (strncmp(lnk, pattern, strlen(pattern)))
+                continue;
+
+            sscanf(lnk, "socket:[%u]", &ino);
+
+            if (process[0] == '\0') {
+                char tmp[1024];
+                FILE *fp;
+
+                snprintf(tmp, sizeof(tmp), "%s/%d/stat", root, pid);
+                if ((fp = fopen(tmp, "r")) != NULL) {
+                    fscanf(fp, "%*d (%[^)])", process);
+                    fclose(fp);
+                }
+            }
+
+            user_ent_add(ino, process, pid, fd);
+        }
+        closedir(dir1);
+    }
+    closedir(dir);
+}
+
+static int find_users(unsigned ino, char *buf, int buflen)
+{
+    struct user_ent *p;
+    int cnt = 0;
+    char *ptr;
+
+    if (!ino)
+        return 0;
+
+    p = user_ent_hash[user_ent_hashfn(ino)];
+    ptr = buf;
+    while (p) {
+        if (p->ino != ino)
+            goto next;
+
+        if (ptr - buf >= buflen - 1)
+            break;
+
+		/* TODO: return 'p' */
+        snprintf(ptr, buflen - (ptr - buf),
+             "(\"%s\",%d,%d),",
+             p->process, p->pid, p->fd);
+        ptr += strlen(ptr);
+        cnt++;
+
+    next:
+        p = p->next;
+    }
+
+    if (ptr != buf)
+        ptr[-1] = '\0';
+
+    return cnt;
+}
+
 static char inet_socket__daddr_doc__[] =
 "daddr() -- get internet socket destination address";
 static PyObject *inet_socket__daddr(struct inet_socket *self,
@@ -491,7 +653,14 @@ out_eof:
 	const int nlmsg_len = self->h->nlmsg_len - NLMSG_LENGTH(sizeof(*r));
 	self->h = NLMSG_NEXT(self->h, self->len);
 
+	if ( show_users > 0 ) {
+		char ubuf[4096];
+    	if (find_users(r->idiag_inode, ubuf, sizeof(ubuf)) > 0)
+    		printf(" users:(%s)", ubuf);
+	}
+
 	return inet_socket__new(r, nlmsg_len);
+
 }
 
 static struct PyMethodDef inet_diag__methods[] = {
@@ -675,6 +844,7 @@ static int filter_bytecompile(struct diag_filter *f, char **bytecode)
 	}
 }
 
+
 /* constructor */
 static char inet_diag_create__doc__[] =
 "create([states, extensions, socktype, src, sport, dst, dport, le_spt, le_dpt, ge_spt, ge_dpt, join=DIAG_FILTER_AND])\n\n\
@@ -698,17 +868,24 @@ static PyObject *inet_diag__create(PyObject *mself __unused, PyObject *args,
 	int le_dpt = -1;
 	int ge_spt = -1;
 	int ge_dpt = -1;
+	int proc   = 0;
 	int join   = DIAG_FILTER_AND;
-	static char *kwlist[] = { "states", "extensions", "socktype", "src", "dst", "sport", "dport", "le_spt", "le_dpt", "ge_spt", "ge_dpt", "join" };
+	static char *kwlist[] = { "states", "extensions", "socktype", "src", "dst", "sport", "dport", "le_spt", "le_dpt", "ge_spt", "ge_dpt", "join", "proc" };
 	struct inet_diag *self = PyObject_NEW(struct inet_diag,
 					      &inet_diag_type);
 	if (self == NULL)
 		return NULL;
 
-	if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iiissiiiiiii", kwlist,
-					 &states, &extensions, &socktype, &src, &dst, &sport, &dport, &le_spt, &le_dpt, &ge_spt, &ge_dpt, &join))
+	if (!PyArg_ParseTupleAndKeywords(args, keywds, "|iiissiiiiiiii", kwlist,
+					 &states, &extensions, &socktype, &src, &dst, &sport, &dport, &le_spt, &le_dpt, &ge_spt, &ge_dpt, &join, &proc))
 		goto out_err;
 
+	/* TODO: THIS SHOULD BE OPTIONAL */
+	if ( proc > 0 ) {
+		show_users++;
+		user_ent_hash_build();
+	}
+
 	self->socket = socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG);
 	if (self->socket < 0)
 		goto out_err;
