~ubuntu-branches/ubuntu/natty/ntop/natty

« back to all changes in this revision

Viewing changes to python/GeoPacketVisualizer.py

  • Committer: Bazaar Package Importer
  • Author(s): Ludovico Cavedon, Jordan Metzmeier, Ludovico Cavedon
  • Date: 2010-12-15 20:06:19 UTC
  • mfrom: (5.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20101215200619-0ojz3iak95ihibun
Tags: 3:4.0.3+dfsg1-1
[ Jordan Metzmeier ]
* New upstream release (Closes: #522042)
* Move data files to /usr/share/ntop (Closes: #595450).
* Package architecture independent data in a separate ntop-data package.
* Use debhelper 7.
* Update Standards-Version to 3.9.1.
* Depend on python-mako.
* Do not include ntop.txt in binary packages as it is a copy of the man
  page.
* Do not include NEWS, as it is outdated.
* Switch to package source version 3.0 (quilt).
* Add password creation to debconf
* Changed init script to fix localization problems (thanks to Alejandro
  Varas <alej0varas@gmail.com>, LP: #257466)
* Remove manual update-rc.d calls from postrm and postinst. debhelper adds
  this for us.
* Add pre-depends on adduser for postinst script.
* Fix errors in the manpages: fix-manpage-errors.patch.
* Added fixes for matching active interfaces.
* Added a watch file.

[ Ludovico Cavedon ]
* Remove direct changes to upstream tree, and move them into specific patch
  files:
  - fix-manpage-errors.patch: fix typos in ntop.8.
  - dot-path.patch: fix path of /usr/bin/dot executable
* Add patches:
  - reduce-autogen-purged-files.patch: prevent agutogen.sh from reamoving
  too many files during cleanup.
  - Add build-without-ntop-darwin.patch, to fix compilation without
  ntop_darwin.c.
* No longer add faq.html, as it is not distributed in the upstream tarball.
* Use ${source:Version} in control file. Have ntop-data recommend
  ntop.
* Rename dirs to ntop.dirs and keep only empty directories that need
  to be created.
* Remove var/lib from ntop.install file, as it is empty (keeping it in
  ntop.dirs).
* Update po files.
* Breaks and Replaces instead of Conflitcs for ntop-data.
* Use a longer package description.
* Remove useless configure options from debian/rules.
* Move private shared libraries libraries in /usr/lib/ntop.
* Add change-plugin-dir.patch for adjusting plugin directory.
* Remove development files.
* Use system library for MochiKit.js.
* Rewrite DEP5 copyright file.
* Repackage upstream tarball in order to remove non-DFSG-compliant code. Add
  get-orig-source.sh script and get-orig-source target in debian/rules.
* Add explanation to README.Debian why geolocation is no longer working.
* Add avoid-copy-maxmind-db.patch to prevent copying of Geo*.dat
  files.
* Remove old unused patches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
'''
 
3
Created on 20 Dec 2009
 
4
 
 
5
@author: Gianluca Medici
 
6
 
 
7
This module is made to show a page inside ntop summarizing the geoLocation of all
 
8
host seen and visualize them on a world map. The map is interactive and shows in addiction
 
9
the information regarding each nation's packets count (represented with different tonality of colours).
 
10
Clicking on a region of a map or on a row of the country's table is possible to zoom to
 
11
that particular nation and see the approximate position of the cities in witch the hosts are located.
 
12
'''
 
13
import decimal
 
14
import ntop
 
15
import host
 
16
import os.path
 
17
import sys
 
18
#import pprint
 
19
# Import modules for CGI handling
 
20
import cgi, cgitb
 
21
 
 
22
from StringIO import StringIO
 
23
 
 
24
exceptions_so_far=0
 
25
 
 
26
try:
 
27
    import json
 
28
 
 
29
    # Imports for mako
 
30
    try:
 
31
        from mako.template import Template
 
32
        from mako.runtime import Context
 
33
        from mako.lookup import TemplateLookup
 
34
        from mako import exceptions
 
35
    except:
 
36
        ntop.printHTMLHeader('ntop Python Configuration Error', 1, 1)
 
37
        ntop.sendString("<b><center><font color=red>Please install <A HREF=http://www.makotemplates.org/>Mako</A> template engine</font><p></b><br>(1) 'sudo yum install python-setuptools' (on RedHat-like systems)<br>(2) 'sudo easy_install Mako'</font></center>")
 
38
        ntop.printHTMLFooter()    
 
39
        exceptions_so_far=1
 
40
except:
 
41
    ntop.printHTMLHeader('ntop Python Configuration Error', 1, 1)
 
42
    ntop.sendString("<b><center><font color=red>Please install JSON support in python</font><p></b><br>E.g. 'sudo apt-get install python-json' (on Debian-like systems)</font></center>")
 
43
    ntop.printHTMLFooter()    
 
44
    exceptions_so_far=1
 
45
 
 
46
# Fix encoding
 
47
reload(sys)
 
48
sys.setdefaultencoding("latin1")
 
49
 
 
50
class Town(object):
 
51
    '''
 
52
    classdocs
 
53
    '''
 
54
    __name=''
 
55
    __latitudine=0
 
56
    __longitudine=0
 
57
    __totalHosts=0
 
58
 
 
59
    def __init__(self, name, latitudine, longitudine, numHosts ):
 
60
        '''
 
61
        Constructor
 
62
        '''
 
63
        self.__name=name.decode('latin1')
 
64
        self.__latitudine=latitudine
 
65
        self.__longitudine=longitudine
 
66
        self.__totalHosts=numHosts
 
67
 
 
68
    def getName(self):
 
69
        return self.__name
 
70
 
 
71
    def getLatitude(self):
 
72
        return self.__latitudine
 
73
 
 
74
    def getLongitude(self):
 
75
        return self.__longitudine
 
76
 
 
77
    def getTotalHosts(self):
 
78
        return self.__totalHosts
 
79
 
 
80
    def addTotal(self, numHosts):
 
81
        self.__totalHosts+=numHosts
 
82
 
 
83
    def getRow(self):
 
84
        return {'c':[{'v':float(self.__latitudine)}, {'v':float(self.__longitudine)} , {'v':self.__totalHosts} , {'v':self.__name}]}
 
85
 
 
86
class Country(object):
 
87
    '''
 
88
    classdocs
 
89
    '''
 
90
    __code = ''
 
91
    __name = ''
 
92
    __total = 0
 
93
    __dictionaryTown = {}
 
94
 
 
95
    def __init__(self, code, name, numHosts):
 
96
        '''
 
97
        Constructor
 
98
        '''
 
99
        self.__code = code
 
100
        
 
101
        self.__name = name.decode('latin1')
 
102
        self.__total = numHosts
 
103
        self.__dictionaryTown = {}
 
104
 
 
105
    def addCity(self, city, latitude, longitude, numHosts):
 
106
        if self.__dictionaryTown.has_key(city):
 
107
            self.__dictionaryTown[city].addTotal(numHosts)
 
108
        else:
 
109
            self.__dictionaryTown[city]= Town(city, latitude, longitude, numHosts)
 
110
 
 
111
    def getCode(self):
 
112
        return self.__code 
 
113
 
 
114
    def getName(self):
 
115
        return self.__name
 
116
 
 
117
    def getTotal(self):
 
118
        return self.__total
 
119
 
 
120
    def addTotal(self, total):
 
121
        self.__total+=total
 
122
 
 
123
    def getDictionaryCities(self):
 
124
        return self.__dictionaryTown
 
125
 
 
126
    def getRow(self):
 
127
        
 
128
        return {'c':[{'v':self.__code}, {'v':self.__total} , {'v':self.__name} ]}
 
129
 
 
130
    def dictToList(self):
 
131
        rows=[]
 
132
        unk=-1
 
133
        i=0
 
134
        for x in self.__dictionaryTown :
 
135
            if self.__dictionaryTown[x].getName() == 'Unknown' and unk == -1:
 
136
                unk=i
 
137
            rows.append(self.__dictionaryTown[x].getRow());
 
138
            i=i+1
 
139
        return {'lista':rows, 'unknown':unk}
 
140
    
 
141
'''
 
142
Return a string of formatted json data for building the countries table and the cities table
 
143
'''
 
144
def getJsonData(dictionaryCountries, totalHosts,unknownCountries, unknownCities):
 
145
    dataJ={'rowsTCountries': None, 'tablesCities': []}
 
146
    mainRows=[]
 
147
    for x in dictionaryCountries:
 
148
        mainRows.append(dictionaryCountries[x].getRow())
 
149
        dataJ['tablesCities'].append({'code':dictionaryCountries[x].getCode(), 'citiesRows': dictionaryCountries[x].dictToList()})
 
150
    
 
151
    dataJ['rowsTCountries']= mainRows
 
152
    dataJ['totalHosts']= totalHosts
 
153
    dataJ['unknownCountries']= unknownCountries
 
154
    dataJ['unknownCities']= unknownCities
 
155
    #pprint.pprint(dataJ, sys.stderr)
 
156
    try:
 
157
        return json.dumps(dataJ, True)
 
158
    except:
 
159
        return 'false'
 
160
 
 
161
if exceptions_so_far == 0:
 
162
    dictionaryCountries = {}
 
163
    
 
164
    totalHosts = 0
 
165
    unknownCountries = 0
 
166
    unknownCities = 0
 
167
    flag = 's'                                  # s (default) for sent packets r for received, b for both
 
168
    SIXDECIMAL = decimal.Decimal(10) ** -6      # decimals are all fixed to 6 es. 0.000000
 
169
    
 
170
    # Parse URL
 
171
    cgitb.enable();
 
172
    
 
173
    form = cgi.FieldStorage();
 
174
    
 
175
    if form.getvalue('OP') == 'Change':
 
176
        flag = form.getvalue('countHosts', 's')
 
177
    
 
178
    while ntop.getNextHost(0):
 
179
        totalHosts += 1
 
180
        geo = host.geoIP()
 
181
        
 
182
        countryCode = geo.get('country_code', '')
 
183
        countryName = geo.get('country_name', '')
 
184
        city = geo.get('city', '')
 
185
        
 
186
        lat = str(geo.get('latitude', '0.000000'))
 
187
        lon = str(geo.get('longitude', '0.000000'))
 
188
        
 
189
        latitude = decimal.Decimal(lat).quantize(SIXDECIMAL)
 
190
        longitude = decimal.Decimal(lon).quantize(SIXDECIMAL)
 
191
        
 
192
        if not countryCode or countryCode == 'EU' or countryCode == 'AP' :      # the country was not found therefore the city was not found, everything in the object is set accordingly
 
193
            countryCode = ''
 
194
            city = ''
 
195
            unknownCountries += 1
 
196
        elif not city :   
 
197
            unknownCities += 1                                     # the country was found but not the city, to list this case the city name is set to Unknown
 
198
            city = 'Unknown'
 
199
            latitude = decimal.Decimal('0.000000')
 
200
            longitude = decimal.Decimal('0.000000')
 
201
 
 
202
        if countryCode :
 
203
            if dictionaryCountries.has_key(countryCode):           # the dictionary of nations already has the nationCode listed 
 
204
                country = dictionaryCountries[countryCode]
 
205
                country.addTotal(1)
 
206
            else:
 
207
                country = Country(countryCode, countryName, 1)
 
208
                dictionaryCountries[countryCode] = country
 
209
 
 
210
        if city: 
 
211
            country.addCity(city, latitude, longitude, 1)          # insert the city found in the citiesDictionary of this nation object
 
212
    
 
213
    if os.getenv('REQUEST_METHOD', 'GET') == 'POST':    
 
214
        ntop.sendHTTPHeader(12)
 
215
        ntop.sendString(getJsonData(dictionaryCountries, totalHosts, unknownCountries, unknownCities))
 
216
    else:
 
217
        ntop.printHTMLHeader('Host Map: Region View', 1, 0)
 
218
        
 
219
        if totalHosts == 0:
 
220
            ntop.printFlagedWarning('No hosts have been detected by ntop yet')
 
221
        elif len(dictionaryCountries) == 0:
 
222
            ntop.printFlagedWarning('No hosts have been successfully geo-located by ntop yet')
 
223
        else:
 
224
            try:
 
225
                basedir =  os.getenv('DOCUMENT_ROOT', '.')+'/python/templates'
 
226
                mylookup = TemplateLookup(directories=[basedir],output_encoding='utf-8', input_encoding='latin1',encoding_errors='replace', default_filters=['decode.utf8'])
 
227
                myTemplate = mylookup.get_template('GeoPacketVisualizer.tmpl')
 
228
                buf = StringIO()
 
229
                ctx = Context(buf, countries = dictionaryCountries, totalHosts = totalHosts, unknownCountries = unknownCountries, 
 
230
                              unknownCities = unknownCities, filename = os.path.basename(__file__))
 
231
                myTemplate.render_context(ctx)
 
232
                ntop.sendString(buf.getvalue())
 
233
            except:
 
234
                ntop.sendString(exceptions.html_error_template().render())
 
235
        
 
236
        ntop.printHTMLFooter()