voorloopnul

About Me

My name is Ricardo Pascal, I'm a developer and sysadmin who lives in Florianopolis/Brazil. I enjoy work with projects related to Linux, Python, Science, Web, Django and Network.

g+ I finally found a place with plenty of space to fly my f330, now I just have to lose the fear of flying... | Vaga de emprego para programador python na lett.com.br O serviço que eles oferecem parece interessante... | "The Horribly Slow Murderer with the Extremely Inefficient Weapon", it's number one in my top 10 worst... | Challenge accepted! One per night til the end of year ( minus weekends )  | TIL: genotoxicity  is not a made up word | +Detectify  i have to say, well done Sirs ! " tl;dr: We uploaded a malicious XML to one of Google’s... | A drug used to treat Cytomegalovirus infections can increase almost four times the survive rate of people... | Physics FTW! | Just to clarify!  | It seems that Brazil actually "chose" the best. | Good tips for dev teams. | it's like our entire body is a baby's soft spot! | Next time I will try with a lighter battery ( < 330g )  | Testing my F330 with multiwii crius | Anyone here who owns a LG 29" 29EA73 know if the full resolution(2560x1080) can be achieved in Ubuntu... | Particularly, I think(as audience) that less slides and more whiteboard is better than no slides. | It would be awesome have something like that in multiwii. #quadrotor | LMFAO!  This is sooooo true! #ComputerNerdProblems   | Good news everyone! Galaxy note 10.1 (n8000) will be updated to android 4.4 http://www.samsungmobi... | In Brazil, cops don't put people in jail. They prefer to beat you in hope to scare you away. |

A python netstat in less than 100 lines of code

Do a python netstat in linux is not really hard, if you know where to look for informations on how to use it. That is the tip: basically any information you could need to clone a system tool, can be retrieved from the system itself. At this particular case what i did was follow these six steps:

  • type ‘man netstat’
  • Read
  • type ‘man proc’
  • Read
  • Code
  • Back to step one

Here is the result:

#!/usr/bin/python

import pwd
import os
import re
import glob

PROC_TCP = "/proc/net/tcp"
STATE = {
        '01':'ESTABLISHED',
        '02':'SYN_SENT',
        '03':'SYN_RECV',
        '04':'FIN_WAIT1',
        '05':'FIN_WAIT2',
        '06':'TIME_WAIT',
        '07':'CLOSE',
        '08':'CLOSE_WAIT',
        '09':'LAST_ACK',
        '0A':'LISTEN',
        '0B':'CLOSING'
        }

def _load():
    ''' Read the table of tcp connections & remove header  '''
    with open(PROC_TCP,'r') as f:
        content = f.readlines()
        content.pop(0)
    return content

def _hex2dec(s):
    return str(int(s,16))

def _ip(s):
    ip = [(_hex2dec(s[6:8])),(_hex2dec(s[4:6])),(_hex2dec(s[2:4])),(_hex2dec(s[0:2]))]
    return '.'.join(ip)

def _remove_empty(array):
    return [x for x in array if x !='']

def _convert_ip_port(array):
    host,port = array.split(':')
    return _ip(host),_hex2dec(port)

def netstat():
    '''
    Function to return a list with status of tcp connections at linux systems
    To get pid of all network process running on system, you must run this script
    as superuser
    '''

    content=_load()
    result = []
    for line in content:
        line_array = _remove_empty(line.split(' '))     # Split lines and remove empty spaces.
        l_host,l_port = _convert_ip_port(line_array[1]) # Convert ipaddress and port from hex to decimal.
        r_host,r_port = _convert_ip_port(line_array[2]) 
        tcp_id = line_array[0]
        state = STATE[line_array[3]]
        uid = pwd.getpwuid(int(line_array[7]))[0]       # Get user from UID.
        inode = line_array[9]                           # Need the inode to get process pid.
        pid = _get_pid_of_inode(inode)                  # Get pid prom inode.
        try:                                            # try read the process name.
            exe = os.readlink('/proc/'+pid+'/exe')
        except:
            exe = None

        nline = [tcp_id, uid, l_host+':'+l_port, r_host+':'+r_port, state, pid, exe]
        result.append(nline)
    return result

def _get_pid_of_inode(inode):
    '''
    To retrieve the process pid, check every running process and look for one using
    the given inode.
    '''
    for item in glob.glob('/proc/[0-9]*/fd/[0-9]*'):
        try:
            if re.search(inode,os.readlink(item)):
                return item.split('/')[2]
        except:
            pass
    return None

if __name__ == '__main__':
    for conn in netstat():
        print conn

by Ricardo Pascal on Jun 27, 2011