root/scapy/main.py

Revision 899:733193ef0717, 9.0 kB (checked in by Phil <phil@secdev.org>, 4 months ago)

Improved temp file management

Line 
1 ## This file is part of Scapy
2 ## See http://www.secdev.org/projects/scapy for more informations
3 ## Copyright (C) Philippe Biondi <phil@secdev.org>
4 ## This program is published under a GPLv2 license
5
6
7 from __future__ import generators
8 import os,sys
9 import __builtin__
10 from error import *
11 import utils
12    
13
14 def _probe_config_file(cf):
15     cf_path = os.path.join(os.environ.get("HOME",""), cf)
16     try:
17         os.stat(cf_path)
18     except OSError:
19         return None
20     else:
21         return cf_path
22
23 def _read_config_file(cf):
24     log_loading.debug("Loading config file [%s]" % cf)
25     try:
26         execfile(cf)
27     except IOError,e:
28         log_loading.warning("Cannot read config file [%s] [%s]" % (cf,e))
29     except Exception,e:
30         log_loading.exception("Error during evaluation of config file [%s]" % cf)
31        
32
33 DEFAULT_PRESTART_FILE = _probe_config_file(".scapy_prestart.py")
34 DEFAULT_STARTUP_FILE = _probe_config_file(".scapy_startup.py")
35
36 def _usage():
37     print """Usage: scapy.py [-s sessionfile] [-c new_startup_file] [-p new_prestart_file] [-C] [-P]
38     -C: do not read startup file
39     -P: do not read pre-startup file"""
40     sys.exit(0)
41
42
43 from config import conf
44 from themes import ColorPrompt
45
46
47 ######################
48 ## Extension system ##
49 ######################
50
51
52 def _load(module):
53     try:
54         mod = __import__(module,globals(),locals(),".")
55         __builtin__.__dict__.update(mod.__dict__)
56     except Exception,e:
57         log_interactive.error(e)
58        
59 def load_module(name):
60     _load("scapy.modules."+name)
61
62 def load_layer(name):
63     _load("scapy.layers."+name)
64
65    
66
67 ##############################
68 ## Session saving/restoring ##
69 ##############################
70
71
72 def save_session(fname=None, session=None, pickleProto=-1):
73     if fname is None:
74         fname = conf.session
75         if not fname:
76             conf.session = fname = utils.get_temp_file(keep=True)
77             log_interactive.info("Use [%s] as session file" % fname)
78     if session is None:
79         session = __builtin__.__dict__["scapy_session"]
80
81     to_be_saved = session.copy()
82        
83     if to_be_saved.has_key("__builtins__"):
84         del(to_be_saved["__builtins__"])
85
86     for k in to_be_saved.keys():
87         if type(to_be_saved[k]) in [types.TypeType, types.ClassType, types.ModuleType]:
88              log_interactive.error("[%s] (%s) can't be saved." % (k, type(to_be_saved[k])))
89              del(to_be_saved[k])
90
91     try:
92         os.rename(fname, fname+".bak")
93     except OSError:
94         pass
95     f=gzip.open(fname,"wb")
96     cPickle.dump(to_be_saved, f, pickleProto)
97     f.close()
98
99 def load_session(fname=None):
100     if fname is None:
101         fname = conf.session
102     try:
103         s = cPickle.load(gzip.open(fname,"rb"))
104     except IOError:
105         s = cPickle.load(open(fname,"rb"))
106     scapy_session = __builtin__.__dict__["scapy_session"]
107     scapy_session.clear()
108     scapy_session.update(s)
109
110 def update_session(fname=None):
111     if fname is None:
112         fname = conf.session
113     try:
114         s = cPickle.load(gzip.open(fname,"rb"))
115     except IOError:
116         s = cPickle.load(open(fname,"rb"))
117     scapy_session = __builtin__.__dict__["scapy_session"]
118     scapy_session.update(s)
119
120
121 ################
122 ##### Main #####
123 ################
124
125 def scapy_delete_temp_files():
126     for f in conf.temp_files:
127         try:
128             os.unlink(f)
129         except:
130             pass
131
132 def scapy_write_history_file(readline):
133     if conf.histfile:
134         try:
135             readline.write_history_file(conf.histfile)
136         except IOError,e:
137             try:
138                 warning("Could not write history to [%s]\n\t (%s)" % (conf.histfile,e))
139                 tmp = utils.get_temp_file(keep=True)
140                 readline.write_history_file(tmp)
141                 warning("Wrote history to [%s]" % tmp)
142             except:
143                 warning("Cound not write history to [%s]. Discarded" % tmp)
144
145
146 def interact(mydict=None,argv=None,mybanner=None,loglevel=20):
147     global session
148     import code,sys,cPickle,os,getopt,re
149     from config import conf
150     conf.interactive = True
151     if loglevel is not None:
152         conf.logLevel=loglevel
153
154     the_banner = "Welcome to Scapy (%s)"
155     if mybanner is not None:
156         the_banner += "\n"
157         the_banner += mybanner
158
159     if argv is None:
160         argv = sys.argv
161
162     import atexit
163     try:
164         import rlcompleter,readline
165     except ImportError:
166         log_loading.info("Can't load Python libreadline or completer")
167         READLINE=0
168     else:
169         READLINE=1
170         class ScapyCompleter(rlcompleter.Completer):
171             def global_matches(self, text):
172                 matches = []
173                 n = len(text)
174                 for lst in [dir(__builtin__), session.keys()]:
175                     for word in lst:
176                         if word[:n] == text and word != "__builtins__":
177                             matches.append(word)
178                 return matches
179        
180    
181             def attr_matches(self, text):
182                 m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
183                 if not m:
184                     return
185                 expr, attr = m.group(1, 3)
186                 try:
187                     object = eval(expr)
188                 except:
189                     object = eval(expr, session)
190                 if isinstance(object, Packet) or isinstance(object, Packet_metaclass):
191                     words = filter(lambda x: x[0]!="_",dir(object))
192                     words += [x.name for x in object.fields_desc]
193                 else:
194                     words = dir(object)
195                     if hasattr( object,"__class__" ):
196                         words = words + rlcompleter.get_class_members(object.__class__)
197                 matches = []
198                 n = len(attr)
199                 for word in words:
200                     if word[:n] == attr and word != "__builtins__":
201                         matches.append("%s.%s" % (expr, word))
202                 return matches
203    
204         readline.set_completer(ScapyCompleter().complete)
205         readline.parse_and_bind("C-o: operate-and-get-next")
206         readline.parse_and_bind("tab: complete")
207    
208    
209     session=None
210     session_name=""
211     STARTUP_FILE = DEFAULT_STARTUP_FILE
212     PRESTART_FILE = DEFAULT_PRESTART_FILE
213
214
215     iface = None
216     try:
217         opts=getopt.getopt(argv[1:], "hs:Cc:Pp:d")
218         for opt, parm in opts[0]:
219             if opt == "-h":
220                 _usage()
221             elif opt == "-s":
222                 session_name = parm
223             elif opt == "-c":
224                 STARTUP_FILE = parm
225             elif opt == "-C":
226                 STARTUP_FILE = None
227             elif opt == "-p":
228                 PRESTART_FILE = parm
229             elif opt == "-P":
230                 PRESTART_FILE = None
231             elif opt == "-d":
232                 conf.logLevel = max(1,conf.logLevel-10)
233        
234         if len(opts[1]) > 0:
235             raise getopt.GetoptError("Too many parameters : [%s]" % " ".join(opts[1]))
236
237
238     except getopt.GetoptError, msg:
239         log_loading.error(msg)
240         sys.exit(1)
241
242     if PRESTART_FILE:
243         _read_config_file(PRESTART_FILE)
244
245     scapy_builtins = __import__("all",globals(),locals(),".").__dict__
246     __builtin__.__dict__.update(scapy_builtins)
247     globkeys = scapy_builtins.keys()
248     globkeys.append("scapy_session")
249     scapy_builtins=None # XXX replace with "with" statement
250     if mydict is not None:
251         __builtin__.__dict__.update(mydict)
252         globkeys += mydict.keys()
253    
254
255     if STARTUP_FILE:
256         _read_config_file(STARTUP_FILE)
257        
258     if session_name:
259         try:
260             os.stat(session_name)
261         except OSError:
262             log_loading.info("New session [%s]" % session_name)
263         else:
264             try:
265                 try:
266                     session = cPickle.load(gzip.open(session_name,"rb"))
267                 except IOError:
268                     session = cPickle.load(open(session_name,"rb"))
269                 log_loading.info("Using session [%s]" % session_name)
270             except EOFError:
271                 log_loading.error("Error opening session [%s]" % session_name)
272             except AttributeError:
273                 log_loading.error("Error opening session [%s]. Attribute missing" %  session_name)
274
275         if session:
276             if "conf" in session:
277                 conf.configure(session["conf"])
278                 session["conf"] = conf
279         else:
280             conf.session = session_name
281             session={"conf":conf}
282            
283     else:
284         session={"conf": conf}
285
286     __builtin__.__dict__["scapy_session"] = session
287
288
289     if READLINE:
290         if conf.histfile:
291             try:
292                 readline.read_history_file(conf.histfile)
293             except IOError:
294                 pass
295         atexit.register(scapy_write_history_file,readline)
296    
297     atexit.register(scapy_delete_temp_files)
298     sys.ps1 = ColorPrompt()
299     code.interact(banner = the_banner % (conf.version), local=session)
300
301     if conf.session:
302         save_session(conf.session, session)
303
304
305     for k in globkeys:
306         try:
307             del(__builtin__.__dict__[k])
308         except:
309             pass
310
311 if __name__ == "__main__":
312     interact()
Note: See TracBrowser for help on using the browser.