move pre-compiled regex to correct method
[bwmon.git] / bwmon / proc.py
blob17da36567c9c26ba51d1ba090fd0851df7948faf
1 # -*- coding: utf-8 -*-
3 from __future__ import absolute_import
5 import os
6 import re
7 import hashlib
9 def get_connections(conn_type='tcp'):
10 """
11 returns the connections from /proc/net/tcp indexed by their id (first
12 column).
13 """
14 f = open('/proc/net/%s' % conn_type, 'r')
15 connections = {}
17 #documentation for /proc/net/tcp in
18 #http://lkml.indiana.edu/hypermail/linux/kernel/0409.1/2166.html
20 for line in f.readlines():
21 line = line.strip()
23 # header line
24 if line.startswith('s'):
25 continue
27 parts = filter(lambda x: x, line.split(' '))
28 index = parts[0].strip()[:-1]
29 local_addr = ip_repr(parts[1])
30 rem_addr = ip_repr(parts[2])
31 inode = int(parts[9])
33 connections[index] = {
34 'local': local_addr,
35 'remote': rem_addr,
36 'inode': inode
39 return connections
42 def ip_repr(ip):
43 """
44 returns the dotted-decimal representation of an IP addresse when given
45 the formated used in /proc/net/tcp
47 >>> ip_repr('C8BCED82:1A0B')
48 '130.237.188.200:6667'
49 """
51 if ':' in ip:
52 ip, port = ip.split(':')
53 else:
54 port = None
56 s = '.'.join([ repr(int(ip[x-2:x], 16)) for x in range(8, 0, -2) ])
57 if port:
58 s += ':%d' % int(port, 16)
60 return s
63 def get_fd_map():
64 """ returns a dictionary mapping filedescriptors to process information"""
66 proc = '/proc/'
67 fd = 'fd'
68 pid_dir = r'\d+'
69 socket_regex = r'socket:\[(\d+)\]'
70 cmdline = 'cmdline'
71 m = {}
73 for pid in os.listdir(proc):
75 # process directories
76 d = os.path.join(proc, pid)
77 if not os.path.isdir(d):
78 continue
80 if not re.match(pid_dir, pid):
81 continue
83 fd_dir = os.path.join(d, fd)
84 for x in os.listdir(fd_dir):
85 path = os.path.join(fd_dir, x)
86 try:
87 f_desc = os.readlink(path)
88 except OSError:
89 continue
91 # search for socket file-descriptors
92 match = re.match(socket_regex, f_desc)
93 if match:
94 inode = int(match.group(1))
95 else:
96 continue
98 cmd_file = open(os.path.join(d, cmdline), 'rb')
99 cmd = cmd_file.read()
101 # Command line arguments are splitted by '\0'
102 cmd = cmd.replace('\0', ' ')
104 m[inode] = {'inode': inode, 'cmd': cmd, 'pid': int(pid)}
106 return m
109 def parse_ip_conntrack():
110 connections = {}
112 # http://www.faqs.org/docs/iptables/theconntrackentries.html
113 for line in open('/proc/net/ip_conntrack'):
114 parts = line.split()
116 entry = {}
117 for (k, v) in [x.split('=', 1) for x in parts if '=' in x]:
118 # key-value pairs occur twice per line; if first key occurs
119 # again, we finish the first entry and start the next one
120 if k in entry:
121 key = get_key(entry)
122 connections[key] = entry
123 entry = {}
125 entry[k] = v
127 key = get_key(entry)
128 connections[key] = entry
130 return connections
133 def get_key(values):
134 src = '%s:%s' % (values['src'], values['sport'])
135 dst = '%s:%s' % (values['dst'], values['dport'])
136 return ip_hash(src, dst)
139 def ip_hash(src_ip, dest_ip):
140 return '%s-%s' % (src_ip, dest_ip)