1 # -*- coding: utf-8 -*-
3 # Copyright 2010 Thomas Perl and Stefan Kögl. All rights reserved.
5 # Developed for a practical course (Large-scaled distributed computing) at the
6 # University of Technology Vienna in the 2010 summer term.
8 # Redistribution and use in source and binary forms, with or without
9 # modification, are permitted provided that the following conditions are met:
11 # 1. Redistributions of source code must retain the above copyright notice,
12 # this list of conditions and the following disclaimer.
14 # 2. Redistributions in binary form must reproduce the above copyright notice,
15 # this list of conditions and the following disclaimer in the documentation
16 # and/or other materials provided with the distribution.
18 # THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21 # EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25 # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 from __future__
import absolute_import
36 def get_connections(conn_type
='tcp'):
37 """Get connections from /proc/net/
39 Read the currently-running connections from the
42 @param conn_type: The connection type ('tcp' or 'udp')
44 f
= open('/proc/net/%s' % conn_type
, 'r')
47 #documentation for /proc/net/tcp in
48 #http://lkml.indiana.edu/hypermail/linux/kernel/0409.1/2166.html
50 for line
in f
.readlines():
54 if line
.startswith('s'):
57 parts
= filter(lambda x
: x
, line
.split(' '))
58 index
= parts
[0].strip()[:-1]
59 local_addr
= ip_repr(parts
[1])
60 rem_addr
= ip_repr(parts
[2])
63 connections
[index
] = {
73 """Get the dotted-decimal representation of an IP
75 @param ip: The IP as formatted in /proc/net/tcp
76 @return: the dotted-decimal representation of an IP
78 >>> ip_repr('C8BCED82:1A0B')
79 '130.237.188.200:6667'
83 ip
, port
= ip
.split(':')
87 s
= '.'.join([ repr(int(ip
[x
-2:x
], 16)) for x
in range(8, 0, -2) ])
89 s
+= ':%d' % int(port
, 16)
95 """Get a filedescriptor-to-process mapping
97 @return: A dictionary mapping file descriptors to process infos
103 socket_regex
= r
'socket:\[(\d+)\]'
107 for pid
in os
.listdir(proc
):
109 # process directories
110 d
= os
.path
.join(proc
, pid
)
111 if not os
.path
.isdir(d
):
114 if not re
.match(pid_dir
, pid
):
117 fd_dir
= os
.path
.join(d
, fd
)
118 for x
in os
.listdir(fd_dir
):
119 path
= os
.path
.join(fd_dir
, x
)
121 f_desc
= os
.readlink(path
)
125 # search for socket file-descriptors
126 match
= re
.match(socket_regex
, f_desc
)
128 inode
= int(match
.group(1))
132 cmd_file
= open(os
.path
.join(d
, cmdline
), 'rb')
133 cmd
= cmd_file
.read()
135 # Command line arguments are splitted by '\0'
136 cmd
= cmd
.replace('\0', ' ')
138 m
[inode
] = {'inode': inode
, 'cmd': cmd
, 'pid': int(pid
)}
143 def parse_ip_conntrack():
144 """Get a parsed representation of /proc/net/ip_conntrack
146 @return: A dictionary of connections
150 if not os
.path
.exists('/proc/net/ip_conntrack'):
151 # conntrack-utils (recent kernels, November 2012)
152 conntrack
= os
.popen('conntrack -L', 'r')
154 # Old "ip_conntrack" kernel module (July 2010)
155 conntrack
= open('/proc/net/ip_conntrack', 'r')
157 # http://www.faqs.org/docs/iptables/theconntrackentries.html
158 for line
in conntrack
:
161 # We only care about TCP and UDP connections
162 if parts
[0] not in ('udp', 'tcp'):
166 for (k
, v
) in [x
.split('=', 1) for x
in parts
if '=' in x
]:
167 # key-value pairs occur twice per line; if first key occurs
168 # again, we finish the first entry and start the next one
171 connections
[key
] = entry
177 connections
[key
] = entry
185 """Build a hashed key out of a ip_conntrack connection
187 This takes the source IP, source port and destination
188 IP and destination port and returns a unique key.
190 @param values: An entry from the ip_conntrack table
191 @return: The hashed key for this connection pair
193 src
= '%s:%s' % (values
['src'], values
['sport'])
194 dst
= '%s:%s' % (values
['dst'], values
['dport'])
195 return ip_hash(src
, dst
)
198 def ip_hash(src_ip
, dest_ip
):
201 @param src_ip: The IP address of the source
202 @param dest_ip: The IP address of the destination
203 @return: A string that combines both parameters
205 return '%s-%s' % (src_ip
, dest_ip
)