2016-10-06_14:19:03 IpPlot printWrokingiplist 2016() m

14,000 hints and counting!
10.4: Convert new plist files between XML and binary
Apple has introduced a new .plist file format in 10.4. You'll notice that you can no longer just edit a .plist file in TextEdit or other text editors. The reason for this is that the files are now binary rather than raw XML.
Luckily for us, there is a command line utility called plutil that can convert back and forth between the two formats. You can convert the .plist file you want to edit to XML format, edit it in TextEdit, then convert back to binary for use. To convert a binary .plist file to XML format for editing, type this in the Terminal:
plutil -convert xml1 some_file.plist
To convert an XML .plist file to binary for use:
plutil -convert binary1 some_other_file.plist
Replace some_file.plist and some_other_file.plist with the actual filenames, obviously...
&&&&•&
Currently 3.42 / 5
&&You rated:
(12 votes cast)
[116,236 views] &
Hint Options
From our Sponsor...
Latest Mountain Lion Hints
User Functions
Lost your ?
What's New:HintsComments last 2 daysNo new comments
Links last 2 weeksNo recent new links
What's New in the Forums?
Hints by Topic-- All Topics --Apps
Desktop Macs
iOS devices
Laptop Macs
OS X Server
Other Hardware
Pick of the Week
Storage Devices
System 10.4
System 10.5
System 10.6
System 10.7
System 10.8
System 10.9
Web Browsers
News from Macworld
From Our Sponsors#! /usr/bin/env python
#############################################################################
## scapy.py --- Interactive packet manipulation tool
see http://www.secdev.org/projects/scapy/
for more informations
## Copyright (C) 2003
Philippe Biondi
## This prog you can redistribute it and/or modify it ##
## under the terms of the GNU General Public License version 2 as
## published by the Free Software F version 2.
## This program is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU
## General Public License for more details.
#############################################################################
# $Log: scapy.py,v $
# Revision 1.0.0.20
# - 802.11 tweaks
# Revision 1.0.0.19
# - added Packet.decode_payload_as()
# Revision 1.0.0.18
# - Added XShortEnumField()
# Revision 1.0.0.17
# - fixed crc32() computation for big endian systems
# Revision 1.0.0.16
# - fix regression introduced in 1.0.0.4 (netstat parsing)
# Revision 1.0.0.15
# - fixed socket creation/attach filter race condition for L2Socket and L3PacketSocket.
No more packets shoud go through the filter.
# Revision 1.0.0.14
# - don't return outgoing packets in L2Socket and L3PacketSocket
# - L2Socket and L3PacketSocket don't catch the exception if conf.dissector=1
# Revision 1.0.0.13
# - enhanced Packet.summary() code
# Revision 1.0.0.12
# - keep tcp/udp ports numeric in traceroute result
# Revision 1.0.0.11
# - added NTP.mysummary()
# Revision 1.0.0.10
# - fixed Ether.summary() (P. Lalet)
# Revision 1.0.0.9
# - moved code to build answering machines' functions into a metaclass
# Revision 1.0.0.8
# - added MobileIP protocol (rfc3344 and friends) (B. Andersson)
# Revision 1.0.0.7
# - changed Ether.mysummary() (P. Lalet)
# - Update of Sebek protocols (P. Lalet)
# Revision 1.0.0.6
# - fix problem in declaraion of answering machine functions
# Revision 1.0.0.5
# - added resolution of numbers from /etc/ethertypes, /etc/protocols and
/etc/services (P. Lalet)
# - tweaked some mysummary() accordingly
# Revision 1.0.0.4
# - Better netstat parsing for OpenBSD (P. Lalet)
# Revision 1.0.0.3
# - fixed regression introduced by previous patch : Gen and Packet are not
classes anymore but types.
# Revision 1.0.0.2
# - added ChangeDefaultValues metaclass to easily make a variant of a protocol
# Revision 1.0.0.1
# Release 1.0.0
# Revision 1.0
# 1.0 release
# Revision 0.9.17.110
# - nothing
# Revision 0.9.17.109
# - replaced use of __builtins__ by globals()
# - promiscuous mode is now default mode
# - added HTML color theme
# Revision 0.9.17.108
# - fix: IP fragmentation offset needs to be 0 for payload to be decoded
(actually fixed in 0.9.17.106)
# Revision 0.9.17.107
# - added 'filter' parameter to PacketList.padding()
# - added PacketList.nzpadding() method
# - added 'lfilter' parameter to sniff()
# Revision 0.9.17.106
# - removed scapy module reloading to prepare interactive mode
# - tweaked interact() function, now fully functionnal
# Revision 0.9.17.105
# - small fix nmap database class
# Revision 0.9.17.104
# - modified Packet.guess_payload_class() semantic : added the payload as parameter
# - fixed TCP.answers() to take in account length of payload
# - added timeout arg to arping()
# Revision 0.9.17.103
# - added a try/catch for get_if_hw_addr
# - fixed the netstat parsing for OpenBSD
# - changed Dot11WEP's key ID field from "key" to "keyid"
# Revision 0.9.17.102
# - added LEShortEnumField
# - added L2CAP layer
# - added Bluetooth supersocket
# - added srbt() and srbt1()
# Revision 0.9.17.101
# - Fixes for 0.9.17.100
# Revision 0.9.17.100
# - added NetBIOS, SMB & Co support (Sebastien Chenevot & Sylvain Sarmejeanne)
# Revision 0.9.17.99
# - WEP support and ICV computation
# Revision 0.9.17.98
# -fixed a smlal bug in graphic traceroute
# Revision 0.9.17.97
# - added WEP ciphering to Dot11WEP
# Revision 0.9.17.96
# - ability to give a WEP key as an argument to unwep()
# Revision 0.9.17.95
# - fixed pcap supersockets warnings
# Revision 0.9.17.94
# - fixed/cleaned ISAKMP
# Revision 0.9.17.93
# - fixed Packet.remove_underlayer() args
# - fixed FieldLenField
# - added Atheros Prism Header linktype
# Revision 0.9.17.92
# - some voip_play() stuff
# Revision 0.9.17.91
# - added BIOCIMMEDIATE option to fix BSD's BPF/pcap/select() behaviour issues
# - made PCAP/DNET the default mode, even for Linux (it seems quicker)
# Revision 0.9.17.90
# - purge ARP cache when changing IP address of an interface
# - fixed loopback interface detection get_if_raw_hwaddr() for dnet
# - changed a bit Dot11PacketList behaviour
# - fixed build() overload by EAP class
# - fixed close()/recv() mix up in L2pcapListenSocket
# Revision 0.9.17.89
# - DNET/PCAP stuff reordering
# Revision 0.9.17.88
# - made Padding not be seen as a payload
# Revision 0.9.17.87
# - added L2 recognition for L2pcapListenSocket
# - workarround for a bug in libpcap/wrapper?. .next() sometimes returns None
# - added consistant get_if_addr() and get_if_raw_addr()
# - added ifadd(), ifdel() and ifchange() methods to Route class
# Revision 0.9.17.86
# - small code cleaning
# Revision 0.9.17.85
# - early BSD port with libdnet and libpcap wrappers
# Revision 0.9.17.84
# - added a usable geolocation database from GeoIP.
# Revision 0.9.17.83
# - fixed fragment() (Peter Hardy)
# Revision 0.9.17.82
# - fixed sndrcv() when given an empty set of packets
# Revision 0.9.17.81
# - Some Sebek layers fixes (Pierre Lalet)
# Revision 0.9.17.80
# - Early IrDA support (Pierre Lalet)
# Revision 0.9.17.79
# - fixed SebekV1 and SebekV2 (Pierre Lalet)
# Revision 0.9.17.78
# - fixed BitField (Pierre Lalet)
# Revision 0.9.17.77
# - added threshold for warnings
# Revision 0.9.17.76
# - Renamed SndRcvAns into SndRcvList
# Revision 0.9.17.75
# - added color display in srloop()
# Revision 0.9.17.74
# - fixed dhcp_request()
# - changed make_table semantic : take one lambda instead of 3
# - fixed import_hexcap()
# - fixed StrLenField
# - changed traceroute() and arping() to also return unanswered packets
# - ls() now sorts its output alphabetically
# - LaTeX color theme for straight copy/paste into your doc.
# Revision 0.9.17.73
# - fixed ARP.answers()' return value
# - made TracerouteResult.graph() use both ASN information source
# Revision 0.9.17.72
# - fix route.route() to handle extended IP sets (ex. 192.168.*.1-5)
# - generalised statistics in packet lists
# - added Dot11PacketList()
# - added some DHCP options
# - fixes in DHCP options building
# - modified unwep() to decrypt a WEP packet if it was not already done
# Revision 0.9.17.71
# - forgotten debug msg in Net()
# Revision 0.9.17.70
# - modified Net() to recognize things like 172.16.*.1-10
# Revision 0.9.17.69
# - fix DHCP
# - added dhcp_request()
# Revision 0.9.17.68
# - first attempt with time skew graphing
# Revision 0.9.17.67
# - use gzip compression for load_object/save_object
# - made RandNum() and Emph() pickable
# - changed prompt color in default color theme
# Revision 0.9.17.66
# - more DHCP work
# Revision 0.9.17.65
# - first attempt to generate libnet C code from a packet
# Revision 0.9.17.64
# - forgot to delete temporary variables in scapy's global scope
# Revision 0.9.17.63
# - added colors, color themes, colored prompt
# Revision 0.9.17.62
# - made it possible to use a PacketList as a parameter for send* or sr*
# Revision 0.9.17.61
# - used init_cookie for ISAKMP.answers()
# - raised an exception in route.make_route if parameters are incomplete
# Revision 0.9.17.60
# - fixed session loading with -s
# - prevented save_session() to trash current session
# - changed AnsweringMachine to make send_reply() a bit more generic
# Revision 0.9.17.59
# - added _elt2show() to PacketList
# - changed PacketList.show() to use _elt2show()
# Revision 0.9.17.58
# - added conversation() to PacketList
# - added padding() to PacketList
# - fixed StrNullField
# - added haslayer_str() to Packet
# - changed Packet.sprintf() to use haslayer_str
# - changed answers() to ask payload if same class as other
# - add count parameter to rdpcap
# Revision 0.9.17.57
# - added StrNullField
# Revision 0.9.17.56
# - LLNumTypes fix
# - Added linktype recognition to PcapWriter class
# Revision 0.9.17.55
# - indentation cosmetic fix
# Revision 0.9.17.54
# - wrpcap() now writes the correct linktype in the pcap file
# Revision 0.9.17.53
# - added ISAKMP transforms decoding
# Revision 0.9.17.52
# - added ikescan()
# - added ISAKMPTransformField
# - fixed PacketList's private methods names do begin only with one "_"
# Revision 0.9.17.51
# - added a prn parameter to PacketList's summary() and nsummary()
# Revision 0.9.17.50
# - make internal methods of PacketResult begins with __
# Revision 0.9.17.49
# - Deprecated display() method (for all objects). Use show() instead.
# Revision 0.9.17.48
# - Modified PacketField to stop at Padding instead of Raw
# - Added PacketLenField
# - More ISAKMP rework. Almost working.
# Revision 0.9.17.47
# - added unwep() method to Dot11 packets
# - fixed 4 missing bytes in Dot11WEP
# Revision 0.9.17.46
# - added a possibility to give a hint for srp() to choose the intended interface
# - added is_promisc() to find boxes in promisc mode (will not always work) (Javier Merino)
# Revision 0.9.17.45
# - added PacketField
# - ISAKMP work
# Revision 0.9.17.44
# - changed PCAP and DNET defaults
# Revision 0.9.17.43
# - ISAKMP work
# Revision 0.9.17.42
# - added make_world_trace() method to TracerouteResult for a xtraceroute-like
# Revision 0.9.17.41
# - Sebek protocol definitions enhancements (Pierre Lalet)
# Revision 0.9.17.40
# - added ARP answering machine (farpd) (Pierre Lalet)
# Revision 0.9.17.39
# - Graphic traceroute enhanced to cope with TCP, UDP, ICMP or other traceroutes
# - ASN clustering in graphic traceroute can be controlled with the "ASN" parameter
# Revision 0.9.17.38
early support
# - RandString()
# Revision 0.9.17.37
# - export_object()/import_object() to copy/paste base64 gzipped pickled objects
# - prevent save_session from deleting unpicklable objects
# - added hexdump() and hexraw() methods to PacketList object
# - Raw packet answers any Raw packet
# - added conf.checkIPaddr to recognize broadcast replies (BOOTP/DHCP)
# Revision 0.9.17.36
# - added GPRS dummy packet class
# Revision 0.9.17.35
# - added l4 parameter to traceroute() for UDP, ICMP and other layer 4 traceroutes
# - tweaked TracerouteResult display()
# Revision 0.9.17.34
# - removed some outdated functions
# Revision 0.9.17.33
# - small simplification of TracerouteResult display() thanks to new sprintf()
conditionnal statement
# Revision 0.9.17.32
# - added conditionnal statements in format strings
# Revision 0.9.17.31
# - removed an uneeded "else" in
# Revision 0.9.17.30
# - re-added node coloring lost code line in traceroute graphing code
# Revision 0.9.17.29
# - fixed need for warning() before it was declared
# Revision 0.9.17.28
# - added ARPingResult to handle arping() results
# - moved ARPing displaying logic to ARPing object
# Revision 0.9.17.27
# - added args todo_graph()
# - added TracerouteResults object to handle traceroute results
# - moved traceroute displaying logic to TracerouteResult object
# - moved traceroute graphing logic to TracerouteResult object
# Revision 0.9.17.26
# - graph_traceroute : added AS clustering, colors, tweaks
# Revision 0.9.17.25
# - added do_graph() to draw GraphViz graphs using SVG output, displayed with ImageMagick
# - added graph_traceroute() to make a graph from multiple traceroutes
# - added timeout parameter to traceroute()
# Revision 0.9.17.24
# - added Sebek v1 and v2 protocols (Pierre Lalet)
# Revision 0.9.17.23
# - addded promisc and iface parameters to L3RawSocket
# Revision 0.9.17.22
# - Improved PacketList with stability by addition and slicing
# - Added plot() to PacketList using Gnuplot
# - Added StrStopField
# - Added conf.debug_disssector to prevent dissector's exception from being catched
# - Added CookedLinux packet type
# - Show linktype number when it is unknown
# Revision 0.9.17.21
# - removed strace in soxmix command line
# - DHCP support (from Mattias Wadman)
# - added missing make_table to PacketList class
# - have UDP class asks its payload for answers()
# Revision 0.9.17.20
# - Early WEP support
# - voip_play() tweaks
# - Added LEShortField for Dot11 SC field
# Revision 0.9.17.19
# - HSRP early support
# - Cisco CSSP Skinny early support
# - added Little Endian IntEnumField
# - added filter() method to PacketList
# - some voip_play() work
# - loop parameter value in send*() is used as the time to sleep between 2 loops
# Revision 0.9.17.18
# - added recv() method to PcapReader to emulate a SuperSocket
# - added "offline" parameter to sniff() to use sniff on pcap files
# - removed voip_play_offline() and renamed voip_play_sniff() to voip_play()
which is now available to play offline
# Revision 0.9.17.17
# - added early PPPoE support (Ralf Ertzinger)
# - fixed DNS summary() to handle empty queries or answers
# Revision 0.9.17.16
# - added VOIP playing functions (not tested)
# Revision 0.9.17.15
# - transfert traceroute() and arping() options to sndrcv() ("retry", etc.)
# - fixed retry option in sndrcv()
# - tweaked AnweringMachine class
# - rewrited airpwn to use AnsweringMachine
# Revision 0.9.17.14
# - added loopback routing
# Revision 0.9.17.13
# - AnsweringMachine working as I wanted!
# Revision 0.9.17.12
# - AnsweringMachine twaking
# - added DNS spoofing answering machine
# Revision 0.9.17.11
# - renamed
ScapyPcapWriter class to PcapWriter
# - added linktype parameter to PcapWriter (William McVey)
# - added PcapReader class (William McVey)
# Revision 0.9.17.10
# - added some text correspondances to Radius code field
# Revision 0.9.17.9
# - early radius support
# Revision 0.9.17.8
# - added "store" parameter to sniff()
# - added AnsweringMachine class to handle request/response protocols
# - replaced bootpd by a AnsweringMachine subclass
# - created DHCP answering machine draft
# Revision 0.9.17.7
# - finished airpwn()
# Revision 0.9.17.6
# - added first version of airpwn() clone
# Revision 0.9.17.5
# - added RIP protocol
# Revision 0.9.17.4
# - added gzip support to sessions saving
# - can force pickle protocol to inferior values for pickle backward compatility
# Revision 0.9.17.3
# - fixed self reloading when launched from a different directory
# - fixed session reloading problems with PacketList() and SndRcvAns()
# - added load_session(), save_session(), update_session()
# Revision 0.9.17.2
# - added nsummary() method to SndRcvList() class
# Revision 0.9.17.1
# Release 0.9.17
# Revision 0.9.16.18
# - added ScapyPcapWriter class (William McVey)
# Revision 0.9.16.17
# - do not need to be named 'scapy.py' anymore
# - use of PacketList() for rdpcap() and sniff()
# - fixed a bug in StrFixedLenField
# - early IKE and ISAKMP support
# Revision 0.9.16.16
# - small fix on bootpd
# Revision 0.9.16.15
# - finished testing ethertype in supersockets to decide wether or not to apply BPF filters
# Revision 0.9.16.14
# - do not apply any BPF filter if ethertype is given to a supersocket (so that ARP requests will work
whatever the conf.except_filter value is)
# Revision 0.9.16.13
# - changed the header and blocked the licence to GPLv2 only
# Revision 0.9.16.12
# - added an independant routing table (conf.route) and methods to manipulate it
# - tweaked results stats
# Revision 0.9.16.11
# - wrapper classes for results presentations and manipulation
# - sndrcv() retry auto adjustment when giving a negative value
# Revision 0.9.16.10
# - added retry option to sndrcv()
# - improved debug class
# - added ottl() and hops() methods for IPTools class
# - improved UDP and ICMP summary()
# Revision 0.9.16.9
# - fix again TCP.answers() and TCPerror.answers()
# Revision 0.9.16.8
# - fixed conf.checkIPsrc behaviour of answers() and hashret() for TCP/UDP/TCPerror/UDPerror
# - added conf.debug_match to keep track of unanswered packets in debug.sent and debug.recv
# Revision 0.9.16.7
# - added LEIntField and StrFixedLenField
# - added partial PrismHeader support
# Revision 0.9.16.6
# - fixed fragment()
# Revision 0.9.16.5
# - fix nmap fingerprint db parsing to handle the new format (Jochen Bartl)
# Revision 0.9.16.4
# - Support for reading big endian pcap files (Pekka Pietikainen)
# Revision 0.9.16.3
# - got rid of some future warnings (N. Bareil )
# - improved BitField() for arbitrary length bit fields (N. Bareil )
# - NTP protocol (N. Bareil )
# Revision 0.9.16.2
# added first sketch of a bootp daemon: bootpd()
# Revision 0.9.16.1
# Release 0.9.16
# Revision 0.9.15.15
# - added more text for DNS codes
# Revision 0.9.15.14
# - fixed the case where IP field is a list of nets
# - randomize IPID in traceroute() to work better with conf.checkIPsrc=0
# - added make_tex_table() and make_lined_table()
# - added IPID_count() to identify machines with their IPID
# - added sport and dport args to fragleak()
# Revision 0.9.15.13
# - srploop() and srloop() improvements
# Revision 0.9.15.12
# - srloop() and srploop() improvements
# Revision 0.9.15.11
# - srloop() and srploop() improvements
# Revision 0.9.15.10
# - added srloop() and srploop() functions
# Revision 0.9.15.9
# Revision 0.9.15.8
# - improved send() and sendp() with parameters loop and verbose
# Revision 0.9.15.7
# - fixed ARP opcodes values
# Revision 0.9.15.6
# - added RARP and IARP req/resp description in ARP operation Enum field
# Revision 0.9.15.5
# - added checkIPID and checkIPsrc options in conf to recognize IP in ICMP errors from broken IP stacks (see conf.__doc__)
# - changed default TCP source port to 20 (Muahahahah!)
# - tweaked TCP summary
# - changed default UDP source and destination ports to 53
# - created import_hexcap() to copy-paste an hexcap from tcpdump -xX, and get a string to feed IP() or ARP() or whatever
# - created make_table() to present results in a table from a list, and functions that map the list to x,y and z=f(x,y).
# Revision 0.9.15.4
# - little enhancements to the DNS packets
# - added dyndns_add() and dyndns_del() (rfc2136)
# - fixed a format string error (3 times)
# Revision 0.9.15.3
# - redesign summary() method
# - fixed Dot11 addresses fields
# Revision 0.9.15.2
# - caching format size (calcsize()) in Field main class
# - allow first packet desassembly to fail in SuperSockets, falling back to Raw
# Revision 0.9.15.1
# Release 0.9.15
# Revision 0.9.14.8
# - small fix for p0f_base
# - lazy loading for p0f, queso and nmap knowledge databases
# Revision 0.9.14.7
# - added a LongField
# - added classes and bonds for 802.11
# - added error handling and magic checks for rdpcap()
# Revision 0.9.14.6
# - had Dot11 working
# Revision 0.9.14.5
# - added summary() method to Packet objects
# Revision 0.9.14.4
# - added SNAP protocol
# - catched broken pipe exception when shild die in sndrcv()
# - fixed default L2socket type in srp() and srp1() (ETH_P_ALL)
# - fixed format string in attach_filter()
# Revision 0.9.14.3
# - fixed the fact that bpf filters were generated in cooked mode, and thus did
# - filter on socket type ETH_P_ARP instead of using a bpf filter for ARP replies
# - fixed the way of handling the SuperSocket close.
# - uniformised the naming for interface parameter : iface instead of iff
# - fixed the FutureWarning for long integers
# - fixed a typo in 3 format strings (%*i instead of %i)
# Revision 0.9.14.2
# -added "-i any" for tcpdump to compile filters even if they don't work on main interface
# - put PPP special case before layer 2 general case in a super socket
# - added th filter parameter to L3RawSocket
# - added a special case in getmacbyip() when loopback interface is concernet
# - added value for RAWIP linktype in pcap capture files
# Revision 0.9.14.1
# Release 0.9.14, from 0.9.13.4
# Revision 0.9.13.4
# - fixed a regression in L3PacketSocket for ppp links
# Revision 0.9.13.3
# - more tweaks on Packet.sprintf(). Added __doc__.
# Revision 0.9.13.2
# - small tweaks in Packet.sprintf()
# Revision 0.9.13.1
# Release 0.9.13
# Revision 0.9.12.9
# - fixed verbose parameter in nmap_fp()
# Revision 0.9.12.8
# - small enhancements in self-documentation
# - added early experiemental support for BOOTP and 802.11
# Revision 0.9.12.7
# - added workarroung python bug 643005 (socket.inet_aton("255.255.255.255"))
# - use answers() method instead of operator
# - added hashret() method : returns a hash that is invariant for a packet and its reply
# - use hashret() in sndrcv() for dramatic improvements for matching replies on big set of packets
# - change report_ports() to return a string instead of printing
# Revision 0.9.12.6
# - improved the __repr__() method of Packet class
# Revision 0.9.12.5
# - added minttl parameter to traceroute()
# Revision 0.9.12.4
# - Improved random number object (thanks to O. Poyen)
# Revision 0.9.12.3
# - fixed a name overlap on "type" in L2ListenSocket and L3PacketSocket (thanks to E. M. Hopper)
# Revision 0.9.12.2
# - externalized conversion from probes to signature with nmap_probes2sig() use probe results from, say, a pcap file
# Revision 0.9.12.1
# Release 0.9.12
# Revision 0.9.11.5
# - Fixed long int conversion in attach_filter()
# Revision 0.9.11.4
# - rectification in SetGen to unroll Gen instances in lists
# - Completed DNS types and qtypes names
# - Small tuning in nmap_match_one_sig()
# - Parallelized nmap_sig()
# Revision 0.9.11.3
# - removed 4 byte IP string autorecognition. Never used and broken for 4 byte names
# - added "islist" flag to fields to distinguish a list value from a list of values
# - changed TCP options from dict to list to preserve order and redundancy
# - added conf.except_filter, to have every command ignore your own traffic (BPF filter)
# - worked in progress for nmap OS fingerprint. Added PU test. Fixed other tests.
# - added nmap_sig2txt() to transform a signature to its text form, suitable for nmap base
# Revision 0.9.11.2
# - small fixes in init_queso()
# - experimental support of nmap fingerprinting (not complete yet)
# Revision 0.9.11.1
# Release 0.9.11
# Revision 0.9.10.8
# - fixed bug in getmacbyip() using dnet module
# - deactivated getmacbyip() using dnet module because it did not resolve unknown IPs
# - added some commands listed by lsc()
# Revision 0.9.10.7
# - some getattr/setattr/delattr enhancements
# Revision 0.9.10.6
# - added experimental support for QueSO OS fingerprinting. Has someone a *recent* database ?
# Revision 0.9.10.5
# - improved the completer to complete with protocol fields
# - small fix in get_working_if()
# Revision 0.9.10.4
# - added option to include padding or not
# Revision 0.9.10.3
# - added L2dnetSocket()
# - improved arping()
# Revision 0.9.10.2
# - fixed the case when the history file does not exist
# Revision 0.9.10.1
# Release 0.9.10
# Revision 0.9.9.15
# - added L3pcapListenSocket
# - fixed L3ListenSocket to use ETH_P_ALL instead of ETH_P_IP by default
# Revision 0.9.9.14
# - reworked L3dnetSocket
# Revision 0.9.9.13
# - added completion (rlcompleter) and history support
# Revision 0.9.9.12
# - bugfixed the close() method of some supersockets
# Revision 0.9.9.11
# - added get_working_if()
# - use get_working_if() for default interface
# Revision 0.9.9.10
# - add DNS layer (do not compress when assemble, answers() is missing)
# Revision 0.9.9.9
# - added EnumField
# - used EnumField for ARP(), ICMP(), IP(), EAPOL(), EAP(),...
# Revision 0.9.9.8
# - better integration of libpcap and libdnet, if available
# Revision 0.9.9.7
# - some tweaks about supersockets close() and __del__() (not satisfied)
# - added L3dnetSocket, that use libdnet and libpcap if available
# Revision 0.9.9.6
# - fixed a regression in bitfield dissection
# - tweaked and fixed a lot of small things arround supersockets
# Revision 0.9.9.5
# - clean session only if it is to be saved
# - forgot to give its name to Padding class
# - fixed the NoPayload comparison tests so that they work on reloaded sessions
# Revision 0.9.9.4
# - Prepared the configuration of L2/L3 supersockets
# Revision 0.9.9.3
# - little fix in L2ListenSocket.__del__()
# - added doc and options in Conf class
# - added promisc support for L3PacketSocket, so that you can get answers to spoofed packets
# Revision 0.9.9.2
# - added extract_padding() method to UDP
# Revision 0.9.9.1
# Release 0.9.9
# Revision 0.9.8.9
# - use cPickle instead of pickle (quicker and works with __getattr__() recursion)
# - small fixes on send() and sendp()
# Revision 0.9.8.8
# - EAPOL overload Ether dst with PAE_GROUP_ADDR
# - tuning in ports_report()
# - tuning in fragleak
# Revision 0.9.8.7
# - uses /usr/bin/env invocation
# Revision 0.9.8.6
# - catch error during payload dissection and consider payload as raw data
# Revision 0.9.8.5
# - srp() becomes srp1() and sr() equivalent for L2 is called srp()
# - hastype() Packet methods renamed to haslayer()
# - added getlayer() Packet method
# - added padding detection for layers that have a length field
# - added fragment() that fragment an IP packet
# - added report_ports() to scan a machine and output LaTeX report
# Revision 0.9.8.4
# - added FlagsField(), used for TCP and IP
# - rfc3514 compliance
# Revision 0.9.8.3
# Added pkt2uptime() : uses TCP timestamp to predict when the machine was booted
# Revision 0.9.8.2
# - fixed sprintf() regression to use attributes from a packet that are not fields (eg: payload)
# Revision 0.9.8.1
# Release 0.9.8
# Revision 0.9.7.9
# - add filter support for sr(), sr1() and srp()
# - use filters for getmacbyip() and traceroute() for better reliability under heavy load
# Revision 0.9.7.8
# - better timeout management in sndrcv
# - bugfixed sys.exit() imbrication issues
# - some self documentation
# - added lsc()command
# Revision 0.9.7.7
# - Added IPTool class, to add commands like whois() to IP layer.
# - Have unknown class attributes be asked to payload before raising an exception.
# Revision 0.9.7.6
# More powerful sprintf format string : %[fmt[r],][cls[:nb].]field% where fmt is a classic one, r can be
# appended for raw substitution (ex: IP.flags=0x18 instead of SA), nb is the number of the layer we want
# (ex: for IP/IP packets, IP:2.src is the src of the upper IP layer). Special case : "%.time" is the creation time.
# Ex : p.sprintf("%.time% %-15s,IP.src% -> %-15s,IP.dst% %IP.chksum% %03xr,IP.proto% %r,TCP.flags%")
# Revision 0.9.7.5
# Added creation time packet. Supported by read/write pcap.
# Revision 0.9.7.4
# Added the NoPayload terminal class
# Revision 0.9.7.3
# Fixed RCS Id
# Revision 0.9.7.2
# Adding RCS Id
from __future__ import generators
RCSID="$Id: scapy.py,v 1.0.0.20
18:01:12 pbi Exp $"
VERSION = RCSID.split()[2]+"beta"
def usage():
print "Usage: scapy.py [-s sessionfile]"
sys.exit(0)
##########[XXX]#=--
Next things to do :
- fields to manage variable length hw addr (ARP, BOOTP, etc.)
- improve pcap capture file support
- better self-doc
##########[XXX]#=--
#############################
##### Logging subsystem #####
#############################
import logging,traceback,time
class ScapyFreqFilter(logging.Filter):
def __init__(self):
logging.Filter.__init__(self)
self.warning_table = {}
def filter(self, record):
wt = conf.warning_threshold
if wt > 0:
stk = traceback.extract_stack(limit=1)
caller = stk[0][1]
tm,nb = self.warning_table.get(caller, (0,0))
ltm = time.time()
if ltm-tm > wt:
if_index mapping
SIOCGIFCOUNT
# get number of devices
# From if.h
IFF_UP = 0x1
# Interface is up.
IFF_BROADCAST = 0x2
# Broadcast address valid.
IFF_DEBUG = 0x4
# Turn on debugging.
IFF_LOOPBACK = 0x8
# Is a loopback net.
IFF_POINTOPOINT = 0x10
# Interface is point-to-point link.
IFF_NOTRAILERS = 0x20
# Avoid use of trailers.
IFF_RUNNING = 0x40
# Resources allocated.
IFF_NOARP = 0x80
# No address resolution protocol.
IFF_PROMISC = 0x100
# Receive all packets.
# From netpacket/packet.h
PACKET_ADD_MEMBERSHIP
PACKET_DROP_MEMBERSHIP = 2
PACKET_RECV_OUTPUT
PACKET_RX_RING
PACKET_STATISTICS
PACKET_MR_MULTICAST
PACKET_MR_PROMISC
PACKET_MR_ALLMULTI
# From bits/socket.h
SOL_PACKET = 263
# From asm/socket.h
SO_ATTACH_FILTER = 26
SOL_SOCKET = 1
# From net/route.h
RTF_UP = 0x0001
# Route usable
# From BSD net/bpf.h
#BIOCIMMEDIATE=0x
BIOCIMMEDIATE=-
MTU = 1600
# file parsing to get some values :
spaces = re.compile("[ \t]+|\n")
IP_PROTOS={}
f=open("/etc/protocols")
for l in f:
if l[0] in ["#","\n"]:
lt = tuple(re.split(spaces, l))
if len(lt) < 3:
IP_PROTOS.update({lt[2]:int(lt[1])})
("Couldn't parse one line from protocols file (" + l + ")")
except IOError:
("Can't open protocols file")
ETHER_TYPES={}
f=open("/etc/ethertypes")
for l in f:
if l[0] in ["#","\n"]:
lt = tuple(re.split(spaces, l))
if len(lt) < 2:
ETHER_TYPES.update({lt[0]:int(lt[1], 16)})
("Couldn't parse one line from ethertypes file (" + l + ")")
except IOError,msg:
("Can't open ethertypes file")
TCP_SERVICES={}
UDP_SERVICES={}
f=open("/etc/services")
for l in f:
if l[0] in ["#","\n"]:
lt = tuple(re.split(spaces, l))
if len(lt) < 2:
if lt[1].endswith("/tcp"):
TCP_SERVICES.update({lt[0]:int(lt[1].split('/')[0])})
elif lt[1].endswith("/udp"):
UDP_SERVICES.update({lt[0]:int(lt[1].split('/')[0])})
log_loading.warning("Couldn't parse one line from protocols file (" + l + ")")
except IOError:
("Can't open services file")
###########
## Tools ##
###########
def sane(x):
for i in x:
j = ord(i)
if (j = 127):
r=r+conf.color_theme.not_printable+"."+conf.color_theme.normal
def hexdump(x):
l = len(x)
for i in range(l):
print "%02X" % ord(x[i]),
if (i % 16 == 15):
print " "+sane(x[i-15:i+1])
if ((l%16) != 0): print "
"*(16-(l%16))+" "+sane(x[l-(l%16):])
def linehexdump(x):
x = str(x)
l = len(x)
for i in range(l):
print "%02X" % ord(x[i]),
print " "+sane(x)
if BIG_ENDIAN:
CRCPOLY=0x04c11db7L
CRCPOLY=0xedb88320L
def crc32(crc, x):
for c in x:
crc ^= ord(c)
for i in range(8):
if crc & 1:
y = CRCPOLY
return crc
def checksum(pkt):
pkt=str(pkt)
if len(pkt) % 2 == 1:
pkt += "\0"
for i in range(len(pkt)/2):
(struct.unpack("!H",pkt[2*i:2*i+2])[0])
s = (s >> 16) + (s & 0xffff)
s += s >> 16
~s & 0xffff
def warning(x):
log_runtime.warning(x)
def mac2str(mac):
return "".join(map(lambda x: chr(int(x,16)), mac.split(":")))
def str2mac(s):
return ("%02x:"*6)[:-1] % tuple(map(ord, s))
def strxor(x,y):
return "".join(map(lambda x,y:chr(ord(x)^ord(y)),x,y))
def atol(x):
ip = inet_aton(x)
except socket.error:
ip = inet_aton(socket.gethostbyname(x))
return struct.unpack("I", ip)[0]
def ltoa(x):
return socket.inet_ntoa(struct.pack("I", x))
def do_graph(graph,type="svg",target="| display"):
"""do_graph(graph, type="svg",target="| display"):
graph: GraphViz graph description
type: output type (svg, ps, gif, jpg, etc.), passed to dot's "-T" option
target: filename or redirect. Defaults pipe to Imagemagick's display program"""
w,r = os.popen2("dot -T %s %s" % (type,target))
w.write(graph)
##############################
## Session saving/restoring ##
##############################
def save_session(fname, session=None, pickleProto=-1):
if session is None:
session = scapy_session
to_be_saved = session.copy()
if to_be_saved.has_key("__builtins__"):
del(to_be_saved["__builtins__"])
for k in to_be_saved.keys():
if type(to_be_saved[k]) in [types.TypeType, types.ClassType, types.ModuleType]:
log_interactive.error("[%s] (%s) can't be saved." % (k, type(to_be_saved[k])))
del(to_be_saved[k])
os.rename(fname, fname+".bak")
except OSError:
f=gzip.open(fname,"w")
cPickle.dump(to_be_saved, f, pickleProto)
def load_session(fname):
s = cPickle.load(gzip.open(fname))
except IOError:
s = cPickle.load(open(fname))
scapy_session.clear()
scapy_session.update(s)
def update_session(fname):
s = cPickle.load(gzip.open(fname))
except IOError:
s = cPickle.load(open(fname))
scapy_session.update(s)
def export_object(obj):
print base64.encodestring(press(cPickle.dumps(obj,2),9))
def import_object(obj=None):
if obj is None:
obj = sys.stdin.read()
return cPickle.loads(gzip.zlib.decompress(base64.decodestring(obj.strip())))
def save_object(fname, obj):
cPickle.dump(obj,gzip.open(fname,"w"))
def load_object(fname):
return cPickle.load(gzip.open(fname))
#################
## Debug class ##
#################
class debug:
####################
## IP Tools class ##
####################
class IPTools:
"""Add more powers to a class that have a "src" attribute."""
def whois(self):
os.system("whois %s" % self.src)
def ottl(self):
t = [32,64,128,255]+[self.ttl]
return t[t.index(self.ttl)+1]
def hops(self):
return self.ottl()-self.ttl-1
##############################
## Routing/Interfaces stuff ##
##############################
class Route:
def __init__(self):
self.resync()
self.s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def resync(self):
self.routes = read_routes()
def __repr__(self):
rt = "Network
Output IP\n"
for net,msk,gw,iface,addr in self.routes:
rt += "%-15s %-15s %-15s %-15s %-15s\n" % (ltoa(net),
ltoa(msk),
def make_route(self, host=None, net=None, gw=None, dev=None):
if host is not None:
thenet,msk = host,32
elif net is not None:
thenet,msk = net.split("/")
msk = int(msk)
raise Exception("make_route: Incorrect parameters. You should specify a host or a net")
if gw is None:
gw="0.0.0.0"
if dev is None:
nhop = thenet
dev,ifaddr,x = self.route(nhop)
ifaddr = get_if_addr(dev)
return (atol(thenet),(1L<<msk)-1, gw, dev, ifaddr)
def add(self, *args, **kargs):
add(net="192.168.1.0/24",gw="1.2.3.4")
self.routes.append(self.make_route(*args,**kargs))
def delt(self,
*args, **kargs):
route = self.make_route(*args,**kargs)
i=self.routes.index(route)
del(self.routes[i])
except ValueError:
warning("no matching route found")
def ifchange(self, iff, addr):
the_addr,the_msk = (addr.split("/")+["32"])[:2]
the_msk = (1L << int(the_msk))-1
the_rawaddr, = struct.unpack("I",inet_aton(the_addr))
the_net = the_rawaddr & the_msk
for i in range(len(self.routes)):
net,msk,gw,iface,addr = self.routes[i]
if iface != iff:
if gw == '0.0.0.0':
self.routes[i] = (the_net,the_msk,gw,iface,the_addr)
self.routes[i] = (net,msk,gw,iface,the_addr)
for i in arp_cache.keys():
del(arp_cache[i])
def ifdel(self, iff):
new_routes=[]
for rt in self.routes:
if rt[3] != iff:
new_routes.append(rt)
self.routes=new_routes
def ifadd(self, iff, addr):
the_addr,the_msk = (addr.split("/")+["32"])[:2]
the_msk = (1L << int(the_msk))-1
the_rawaddr, = struct.unpack("I",inet_aton(the_addr))
the_net = the_rawaddr & the_msk
self.routes.append((the_net,the_msk,'0.0.0.0',iff,the_addr))
def route(self,dst):
# Transform "192.168.*.1-5" to one IP of the set
dst = dst.split("/")[0]
dst = dst.replace("*","0")
l = dst.find("-")
if l.find("Mtu") >= 0:
mtu = True
if ok == 0:
dest,gw,fl,ref,use,mtu,netif = l.split()[:7]
dest,gw,fl,ref,use,netif = l.split()[:6]
if dest == "default":
netmask = 0L
if "/" in dest:
dest,netmask = dest.split("/")
netmask = (1L << int(netmask))-1
netmask = (1L << ((dest.count(".")+1)*8))-1
dest += ".0"*(3-dest.count("."))
dest, = struct.unpack("I",inet_aton(dest))
if not "G" in fl:
gw = '0.0.0.0'
ifaddr = get_if_addr(netif)
routes.append((dest,netmask,gw,netif,ifaddr))
return routes
def read_interfaces():
i = dnet.intf()
ifflist = {}
def addif(iff,lst):
if not iff.has_key("addr"):
if not iff.has_key("link_addr"):
rawip = iff["addr"].data
ip = socket.inet_ntoa(rawip)
rawll = iff["link_addr"].data
ll = str2mac(rawll)
lst[iff["name"]] = (rawll,ll,rawip,ip)
i.loop(addif, ifflist)
return ifflist
def read_routes():
f=open("/proc/net/route","r")
routes = []
s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x","lo"))
addrfamily = struct.unpack("h",ifreq[16:18])[0]
if addrfamily == socket.AF_INET:
ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x","lo"))
msk = struct.unpack("I",ifreq2[20:24])[0]
dst = struct.unpack("I",ifreq[20:24])[0] & msk
ifaddr = socket.inet_ntoa(ifreq[20:24])
routes.append((dst, msk, "0.0.0.0", "lo", ifaddr))
warning("Interface lo: unkownn address family (%i)"% addrfamily)
for l in f.readlines()[1:]:
iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split()
if int(flags,16) & RTF_UP == 0:
ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff))
addrfamily = struct.unpack("h",ifreq[16:18])[0]
if addrfamily == socket.AF_INET:
ifaddr = socket.inet_ntoa(ifreq[20:24])
warning("Interface %s: unkownn address family (%i)"%(iff, addrfamily))
routes.append((long(dst,16),
long(msk,16),
socket.inet_ntoa(struct.pack("I",long(gw,16))),
iff, ifaddr))
return routes
def get_if(iff,cmd):
s=socket.socket()
ifreq = ioctl(s, cmd, struct.pack("16s16x",iff))
return ifreq
def get_if_index(iff):
return int(struct.unpack("I",get_if(iff, SIOCGIFINDEX)[16:20])[0])
def get_if_addr(iff):
return socket.inet_ntoa(get_if_raw_addr(iff))
def get_if_hwaddr(iff):
addrfamily, mac = get_if_raw_hwaddr(iff)
if addrfamily in [ARPHDR_ETHER,ARPHDR_LOOPBACK]:
return str2mac(mac)
raise Exception("Unsupported address family (%i)"%addrfamily)
#####################
## ARP cache stuff ##
#####################
ARPTIMEOUT=120
# XXX Fill arp_cache with /etc/ether and arp cache
arp_cache={}
if 0 and DNET: ## XXX Can't use this because it does not resolve IPs not in cache
dnet_arp_object = dnet.arp()
def getmacbyip(ip):
iff,a,gw = conf.route.route(ip)
if iff == "lo":
return "ff:ff:ff:ff:ff:ff"
if gw != "0.0.0.0":
res = dnet_arp_object.get(dnet.addr(ip))
if res is None:
return None
return res.ntoa()
def getmacbyip(ip):
iff,a,gw = conf.route.route(ip)
if iff == "lo":
return "ff:ff:ff:ff:ff:ff"
if gw != "0.0.0.0":
if arp_cache.has_key(ip):
mac, timeout = arp_cache[ip]
if timeout and (time.time()-timeout < ARPTIMEOUT):
return mac
res = srp1(Ether(dst=ETHER_BROADCAST)/ARP(op="who-has", pdst=ip),
type=ETH_P_ARP,
iface = iff,
timeout=2,
verbose=0)
if res is not None:
mac = res.payload.hwsrc
arp_cache[ip] = (mac,time.time())
return mac
return None
####################
## Random numbers ##
####################
class RandField:
class RandNum(RandField):
def __init__(self, min, max):
self.min = min
self.max = max
def randint(self):
# XXX: replace with sth that guarantee unicity
return random.randint(self.min, self.max)
def __getattr__(self, attr):
return getattr(self.randint(), attr)
class RandByte(RandNum):
def __init__(self):
RandNum.__init__(self, 0, 255)
class RandShort(RandNum):
def __init__(self):
RandNum.__init__(self, 0, 65535)
class RandInt(RandNum):
def __init__(self):
won't be reached because max+1 must be int
# and +1 is longint. (random module limitation)
RandNum.__init__(self, 0, )
class RandString(RandField):
def __init__(self, size, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"):
self.chars = chars
self.size = size
def randstr(self):
for i in range(self.size):
s += random.choice(self.chars)
def __getattr__(self, attr):
return getattr(self.randstr(), attr)
################
## Generators ##
################
class Gen(object):
def __iter__(self):
return iter([])
class SetGen(Gen):
def __init__(self, set):
if type(set) is list:
self.set = set
elif isinstance(set, PacketList):
self.set = list(set)
self.set = [set]
def transf(self, element):
return element
def __iter__(self):
for i in self.set:
if (type(i) is tuple) and (len(i) == 2):
(i[0] <= i[1]):
while j <= i[1]:
elif isinstance(i, Gen):
for j in i:
def __repr__(self):
return "" % self.set.__repr__()
class Net(Gen):
"""Generate a list of IPs from a network address or a name"""
name = "ip"
ipaddress = re.compile(r"^(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)\.(\*|[0-2]?[0-9]?[0-9](-[0-2]?[0-9]?[0-9])?)(/[0-3]?[0-9])?$")
def __init__(self, net):
self.repr=net
tmp=net.split('/')+["32"]
if not self.ipaddress.match(net):
tmp[0]=socket.gethostbyname(tmp[0])
netmask = int(tmp[1])
def parse_digit(a,netmask):
netmask = min(8,max(netmask,0))
if a == "*":
a = (0,256)
elif a.find("-") >= 0:
x,y = map(int,a.split("-"))
(0xffL<>(8-netmask))))+1)
a = (int(a) & (0xffL<>(8-netmask)))+1)
self.parsed = map(lambda x,y: parse_digit(x,y), tmp[0].split("."), map(lambda x,nm=netmask: x-nm, (8,16,24,32)))
def __iter__(self):
for d in xrange(*self.parsed[3]):
for c in xrange(*self.parsed[2]):
for b in xrange(*self.parsed[1]):
for a in xrange(*self.parsed[0]):
yield "%i.%i.%i.%i" % (a,b,c,d)
def __repr__(self):
return "" % self.repr
#############
## Results ##
#############
class PacketList:
def __init__(self, res, name="PacketList", stats=None):
if stats is None:
stats = [ TCP,UDP,ICMP ]
self.stats = stats
self.res = res
self.listname = name
def _elt2pkt(self, elt):
return elt
def _elt2sum(self, elt):
return elt.summary()
def _elt2show(self, elt):
return self._elt2sum(elt)
def __repr__(self):
stats=dict.fromkeys(self.stats,0) ## needs python >= 2.3
stats = dict(map(lambda x: (x,0), self.stats))
for r in self.res:
for p in stats:
if self._elt2pkt(r).haslayer(p):
stats[p] += 1
other += 1
for p in stats:
s += " %s%s%s:%s%i%s" % (conf.color_theme.packetlist_proto,
conf.color_theme.punct,
conf.color_theme.packetlist_value,
conf.color_theme.punct)
s += " %sOther%s:%s%i%s" % (conf.color_theme.packetlist_proto,conf.color_theme.punct,
conf.color_theme.packetlist_value,
conf.color_theme.punct)
return "%s%s" % (conf.color_theme.punct,
conf.color_theme.packetlist_name,
self.listname,
conf.color_theme.punct,
conf.color_theme.normal,
def __getattr__(self, attr):
return getattr(self.res, attr)
def __getslice__(self, *args, **kargs):
return self.__class__(self.res.__getslice__(*args, **kargs),
name="mod %s"%self.listname)
def __add__(self, other):
return self.__class__(self.res+other.res,
name="%s+%s"%(self.listname,other.listname))
def summary(self, prn=None, filter=None):
for r in self.res:
if filter is not None:
if not filter(r):
if prn is None:
print self._elt2sum(r)
print prn(r)
def nsummary(self,prn=None, filter=None):
for i in range(len(self.res)):
if filter is not None:
if not filter(self.res[i]):
if prn is None:
print "%04i %s" % (i,self._elt2sum(self.res[i]))
print "%04i %s" % (i,prn(self.res[i]))
def display(self): # Deprecated. Use show()
self.show()
def show(self):
for i in range(len(self.res)):
print "%04i %s" % (i,self._elt2show(self.res[i]))
def filter(self, func):
return self.__class__(filter(func,self.res),
name="filtered %s"%self.listname)
def make_table(self, *args, **kargs):
return make_table(self.res, *args, **kargs)
def make_lined_table(self, *args, **kargs):
return make_lined_table(self.res, *args, **kargs)
def make_tex_table(self, *args, **kargs):
return make_tex_table(self.res, *args, **kargs)
def plot(self, f, **kargs):
g=Gnuplot.Gnuplot()
g.plot(Gnuplot.Data(map(f,self.res), **kargs))
def hexdump(self):
for p in self:
hexdump(self._elt2pkt(p))
def hexraw(self):
for i in range(len(self.res)):
p = self._elt2pkt(self.res[i])
print "%04i %s %s" % (i,p.sprintf("%.time%"),self._elt2sum(self.res[i]))
if p.haslayer(Raw):
hexdump(p.getlayer(Raw).load)
def padding(self, filter=None):
for i in range(len(self.res)):
p = self._elt2pkt(self.res[i])
if p.haslayer(Padding):
if not filter or filter(p):
print "%04i %s %s" % (i,p.sprintf("%.time%"),self._elt2sum(self.res[i]))
hexdump(p.getlayer(Padding).load)
def nzpadding(self, filter=None):
for i in range(len(self.res)):
p = self._elt2pkt(self.res[i])
if p.haslayer(Padding):
pad = p.getlayer(Padding).load
if pad == "\x00"*len(pad):
if not filter or filter(p):
print "%04i %s %s" % (i,p.sprintf("%.time%"),self._elt2sum(self.res[i]))
hexdump(p.getlayer(Padding).load)
def conversations(self, getsrc=None, getdst=None,**kargs):
if getsrc is None:
getsrc = lambda x:x.getlayer(IP).src
if getdst is None:
getdst = lambda x:x.getlayer(IP).dst
for p in self.res:
p = self._elt2pkt(p)
c = (getsrc(p),getdst(p))
#XXX warning()
conv[c] = conv.get(c,0)+1
gr = 'digraph "conv" {\n'
for s,d in conv:
gr += '\t "%s" -> "%s"\n' % (s,d)
gr += "}\n"
do_graph(gr, **kargs)
def timeskew_graph(self, ip, **kargs):
b = filter(lambda x:x.haslayer(IP) and x.getlayer(IP).src == ip and x.haslayer(TCP), self.res)
for p in b:
opts = p.getlayer(TCP).options
for o in opts:
if o[0] == "Timestamp":
c.append((p.time,o[1][0]))
d = map(lambda (x,y): (x%2000,((x-c[0][0])-((y-c[0][1])/1000.0))),c)
g = Gnuplot.Gnuplot()
g.plot(Gnuplot.Data(d,**kargs))
class Dot11PacketList(PacketList):
def __init__(self, res, name="Dot11List", stats=None):
if stats is None:
stats = [Dot11WEP, Dot11Beacon, UDP, ICMP, TCP]
PacketList.__init__(self, res, name, stats)
def toEthernet(self):
data = map(lambda x:x.getlayer(Dot11), filter(lambda x : x.haslayer(Dot11) and x.type == 2, self.res))
for p in data:
q = p.copy()
r2.append(Ether()/q.payload.payload.payload) #Dot11/LLC/SNAP/IP
return PacketList(r2,name="Ether from %s"%self.listname)
class SndRcvList(PacketList):
def __init__(self, res, name="Results", stats=None):
PacketList.__init__(self, res, name, stats)
def _elt2pkt(self, elt):
return elt[1]
def _elt2sum(self, elt):
return "%s ==> %s" % (elt[0].summary(),elt[1].summary())
class ARPingResult(SndRcvList):
def __init__(self, res, name="ARPing", stats=None):
PacketList.__init__(self, res, name, stats)
def display(self):
for s,r in self.res:
print r.sprintf("%Ether.src% %ARP.psrc%")
class TracerouteResult(SndRcvList):
def __init__(self, res, name="Traceroute", stats=None):
PacketList.__init__(self, res, name, stats)
self.graphdef = None
self.graphASN = 0
self.hloc = None
self.nloc = None
def display(self): # Deprecated. Use show()
self.show()
def show(self):
return self.make_table(lambda (s,r): (s.sprintf("%IP.dst%:{TCP:tcp%ir,TCP.dport%}{UDP:udp%ir,UDP.dport%}{ICMP:ICMP}"),
r.sprintf("%-15s,IP.src% {TCP:%TCP.flags%}{ICMP:%ir,ICMP.type%}")))
def world_trace(self):
ports_done = {}
for s,r in self.res:
ips[r.src] = None
if s.haslayer(TCP) or s.haslayer(UDP):
trace_id = (s.src,s.dst,s.proto,s.dport)
elif s.haslayer(ICMP):
trace_id = (s.src,s.dst,s.proto,s.type)
trace_id = (s.src,s.dst,s.proto,0)
trace = rt.get(trace_id,{})
if not r.haslayer(ICMP) or r.type != 11:
if ports_done.has_key(trace_id):
ports_done[trace_id] = None
trace[s.ttl] = r.src
rt[trace_id] = trace
for trace_id in rt:
trace = rt[trace_id]
loctrace = []
for i in range(max(trace.keys())):
ip = trace.get(i,None)
if ip is None:
loc = locate_ip(ip)
if loc is None:
loctrace.append((ip,loc)) # no labels yet
loctrace.append(loc)
if loctrace:
trt[trace_id] = loctrace
tr = map(lambda x: Gnuplot.Data(x,with="lines"), trt.values())
g = Gnuplot.Gnuplot()
world = Gnuplot.File(conf.gnuplot_world,with="lines")
g.plot(world,*tr)
def make_graph(self,ASN):
self.graphASN = ASN
ports = {}
ports_done = {}
for s,r in self.res:
ips[r.src] = None
if s.haslayer(TCP) or s.haslayer(UDP):
trace_id = (s.src,s.dst,s.proto,s.dport)
elif s.haslayer(ICMP):
trace_id = (s.src,s.dst,s.proto,s.type)
trace_id = (s.src,s.dst,s.proto,0)
trace = rt.get(trace_id,{})
if not r.haslayer(ICMP) or r.type != 11:
if ports_done.has_key(trace_id):
ports_done[trace_id] = None
p = ports.get(r.src,[])
if r.haslayer(TCP):
p.append(r.sprintf(" %TCP.sport%: %TCP.flags%"))
trace[s.ttl] = r.sprintf('"%IP.src%":T%ir,TCP.sport%')
elif r.haslayer(UDP):
p.append(r.sprintf(" %UDP.sport%"))
trace[s.ttl] = r.sprintf('"%IP.src%":U%ir,UDP.sport%')
elif r.haslayer(ICMP):
p.append(r.sprintf(" ICMP %ICMP.type%"))
trace[s.ttl] = r.sprintf('"%IP.src%":I%ir,ICMP.type%')
p.append(r.sprintf(" IP %IP.proto%"))
trace[s.ttl] = r.sprintf('"%IP.src%":P%ir,IP.proto%')
ports[r.src] = p
trace[s.ttl] = r.sprintf('"%IP.src%"')
rt[trace_id] = trace
# Fill holes with unk%i nodes
blackholes = []
for rtk in rt:
trace = rt[rtk]
k = trace.keys()
for n in range(min(k), max(k)):
if not trace.has_key(n):
trace[n] = "unk%i" % unk
if not ports_done.has_key(rtk):
if rtk[2] == 1: #ICMP
bh = "%s %i" % (rtk[1],rtk[3])
elif rtk[2] == 6: #TCP
bh = "%s:%i/tcp" % (rtk[1],rtk[3])
elif rtk[2] == 17: #UDP
bh = '%s:%i/udp' % (rtk[1],rtk[3])
bh = '%s,proto %i' % (rtk[1],rtk[2])
ips[bh] = None
bhip[rtk[1]] = bh
bh = '"%s"' % bh
trace[max(k)+1] = bh
blackholes.append(bh)
# Find AS numbers
def getASNlist_radb(list):
def parseWhois(x):
asn,desc = None,""
for l in x.splitlines():
if not asn and l.startswith("origin:"):
asn = l[7:].strip()
if l.startswith("descr:"):
desc += r"\n"
desc += l[6:].strip()
if asn is not None and desc:
return asn,desc.strip()
ASNlist = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("whois.ra.net",43))
for ip in list:
s.send("-k %s\n" % ip)
asn,desc = parseWhois(s.recv(8192))
ASNlist.append((ip,asn,desc))
return ASNlist
def getASNlist_cymru(list):
ASNlist = []
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("",43))
s.send("begin\r\n"+"\r\n".join(list)+"\r\nend\r\n")
l = s.recv(8192)
if l == "":
for l in r.splitlines()[1:]:
asn,ip,desc = map(str.strip, l.split("|"))
if asn == "NA":
asn = int(asn)
ASNlist.append((ip,asn,desc))
return ASNlist
ASN_query_list = dict.fromkeys(map(lambda x:x.split(":")[0],ips)).keys()
if ASN in [1,2]:
ASNlist = getASNlist_cymru(ASN_query_list)
elif ASN == 3:
ASNlist = getASNlist_radb(ASN_query_list)
ASNlist = []
if ASN == 1:
ASN_ans_list = map(lambda x:x[0], ASNlist)
ASN_remain_list = filter(lambda x: x not in ASN_ans_list, ASN_query_list)
if ASN_remain_list:
ASNlist += getASNlist_radb(ASN_remain_list)
for ip,asn,desc, in ASNlist:
if asn is None:
iplist = ASNs.get(asn,[])
if ip in bhip:
if ip in ports:
iplist.append(ip)
iplist.append(bhip[ip])
iplist.append(ip)
ASNs[asn] = iplist
ASDs[asn] = desc
def makecol(lstcol):
for i in range(len(lstcol)):
for j in range(len(lstcol)):
for k in range(len(lstcol)):
if i != j or j != k or k != i:
b.append('"#%s%s%s"' % (lstcol[(i+j)%len(lstcol)],lstcol[(j+k)%len(lstcol)],lstcol[(k+i)%len(lstcol)]))
backcolorlist=makecol(["60","86","ba","ff"])
forecolorlist=makecol(["a0","70","40","20"])
clustcol = 0
edgecol = 0
s = "digraph trace {\n"
s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
s += "\n#ASN clustering\n"
for asn in ASNs:
s += '\tsubgraph cluster_%s {\n' % asn
s += '\t\tcolor=%s;' % backcolorlist[clustcol%(len(backcolorlist))]
s += '\t\tnode [fillcolor=%s,style=filled];' % backcolorlist[clustcol%(len(backcolorlist))]
clustcol += 1
s += '\t\tfontsize = 10;'
s += '\t\tlabel = "%s\\n[%s]"\n' % (asn,ASDs[asn])
for ip in ASNs[asn]:
s += '\t\t"%s";\n'%ip
s += "\t}\n"
s += "#endpoints\n"
for p in ports:
s += '\t"%s" [shape=record,color=black,fillcolor=green,style=filled,label="%s|%s"];\n' % (p,p,"|".join(ports[p]))
s += "\n#Blackholes\n"
for bh in blackholes:
s += '\t%s [shape=octagon,color=black,fillcolor=red,style=filled];\n' % bh
s += "\n\tnode [shape=ellipse,color=black,style=solid];\n\n"
for rtk in rt:
s += "#---[%s\n" % `rtk`
s += '\t\tedge [color=%s];\n' % forecolorlist[edgecol%(len(forecolorlist))]
edgecol += 1
trace = rt[rtk]
k = trace.keys()
for n in range(min(k), max(k)):
s += '\t%s ->\n' % trace[n]
s += '\t%s;\n' % trace[max(k)]
s += "}\n";
self.graphdef = s
def graph(self, ASN=1, **kargs):
"""x.graph(ASN=1, other args):
ASN=0 : no clustering
ASN=1 : use whois.cymru.net AS clustering
ASN=2 : use whois.ra.net AS clustering
other args are passed to do_graph()"""
if self.graphdef is None or self.graphASN != ASN:
self.make_graph(ASN)
do_graph(self.graphdef, **kargs)
############
## Fields ##
############
class Field:
def __init__(self, name, default, fmt="H"):
self.name = name
if fmt[0] in "@=!":
self.fmt = fmt
self.fmt = "!"+fmt
self.default = self.any2i(None,default)
self.sz = struct.calcsize(self.fmt)
def h2i(self, pkt, x):
def i2h(self, pkt, x):
def m2i(self, pkt, x):
def i2m(self, pkt, x):
if x is None:
def any2i(self, pkt, x):
def i2repr(self, pkt, x):
if x is None:
return repr(self.i2h(pkt,x))
def addfield(self, pkt, s, val):
return s+struct.pack(self.fmt, self.i2m(pkt,val))
def getfield(self, pkt, s):
s[self.sz:], self.m2i(pkt, struct.unpack(self.fmt, s[:self.sz])[0])
def do_copy(self, x):
if hasattr(x, "copy"):
return x.copy()
elif type(x) is list:
return x[:]
def __eq__(self, other):
return self.name == other
def __hash__(self):
return hash(self.name)
def __repr__(self):
return self.name
def copy(self):
return copy.deepcopy(self)
class Emph:
def __init__(self, fld):
self.fld = fld
def __getattr__(self, attr):
return getattr(self.fld,attr)
class MACField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "6s")
def i2m(self, pkt, x):
return mac2str(x)
def m2i(self, pkt, x):
return str2mac(x)
def any2i(self, pkt, x):
if type(x) is str and len(x) is 6:
x = self.m2i(pkt, x)
def i2repr(self, pkt, x):
return self.i2h(pkt, x)
class DestMACField(MACField):
def __init__(self, name):
MACField.__init__(self, name, None)
def i2h(self, pkt, x):
if x is None:
dstip = None
if isinstance(pkt.payload, IP):
dstip = pkt.payload.dst
elif isinstance(pkt.payload, ARP):
dstip = pkt.payload.pdst
if isinstance(dstip, Gen):
warning("Dest mac not calculated if more than 1 dest IP (%s)"%repr(dstip))
return None
x = "ff:ff:ff:ff:ff:ff"
if dstip is not None:
m=getmacbyip(dstip)
warning("Mac address for %s not found\n"%dstip)
return MACField.i2h(self, pkt, x)
def i2m(self, pkt, x):
return MACField.i2m(self, pkt, self.i2h(pkt, x))
class SourceMACField(MACField):
def __init__(self, name):
MACField.__init__(self, name, None)
def i2h(self, pkt, x):
if x is None:
dstip = None
if isinstance(pkt.payload, IP):
dstip = pkt.payload.dst
elif isinstance(pkt.payload, ARP):
dstip = pkt.payload.pdst
if isinstance(dstip, Gen):
warning("Source mac not calculated if more than 1 dest IP (%s)"%repr(dstip))
return None
x = "00:00:00:00:00:00"
if dstip is not None:
iff,a,gw = conf.route.route(dstip)
m = get_if_hwaddr(iff)
return MACField.i2h(self, pkt, x)
def i2m(self, pkt, x):
return MACField.i2m(self, pkt, self.i2h(pkt, x))
class ARPSourceMACField(MACField):
def __init__(self, name):
MACField.__init__(self, name, None)
def i2h(self, pkt, x):
if x is None:
dstip = pkt.pdst
if isinstance(dstip, Gen):
warning("Source mac not calculated if more than 1 dest IP (%s)"%repr(dstip))
return None
x = "00:00:00:00:00:00"
if dstip is not None:
iff,a,gw = conf.route.route(dstip)
m = get_if_hwaddr(iff)
return MACField.i2h(self, pkt, x)
def i2m(self, pkt, x):
return MACField.i2m(self, pkt, self.i2h(pkt, x))
class Dot11AddrMACField(MACField):
def is_applicable(self, pkt):
def addfield(self, pkt, s, val):
if self.is_applicable(pkt):
return MACField.addfield(self, pkt, s, val)
def getfield(self, pkt, s):
if self.is_applicable(pkt):
return MACField.getfield(self, pkt, s)
return s,None
class Dot11Addr2MACField(Dot11AddrMACField):
def is_applicable(self, pkt):
if pkt.type == 1:
return pkt.subtype in [ 0xb, 0xa, 0xe, 0xf] # RTS, PS-Poll, CF-End, CF-End+CF-Ack
class Dot11Addr3MACField(Dot11AddrMACField):
def is_applicable(self, pkt):
if pkt.type in [0,2]:
class Dot11Addr4MACField(Dot11AddrMACField):
def is_applicable(self, pkt):
if pkt.type == 2:
if pkt.FCfield & 0x3 == 0x3: # To-DS and From-DS are set
class IPField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "4s")
def h2i(self, pkt, x):
if type(x) is str:
inet_aton(x)
except socket.error:
x = Net(x)
elif type(x) is list:
x = map(Net, x)
def i2m(self, pkt, x):
return inet_aton(x)
def m2i(self, pkt, x):
return socket.inet_ntoa(x)
def any2i(self, pkt, x):
if type(x) is str and len(x) == 4:
x = self.m2i(pkt, x)
return self.h2i(pkt,x)
def i2repr(self, pkt, x):
return self.i2h(pkt, x)
class SourceIPField(IPField):
def __init__(self, name, dstname):
IPField.__init__(self, name, None)
self.dstname = dstname
def i2m(self, pkt, x):
if x is None:
iff,x,gw = conf.route.route(getattr(pkt,self.dstname))
return IPField.i2m(self, pkt, x)
def i2h(self, pkt, x):
if x is None:
dst=getattr(pkt,self.dstname)
if isinstance(dst,Gen):
r = map(conf.route.route, dst)
if r[0] == r[-1]:
warning("More than one possible route for %s"%repr(dst))
return None
iff,x,gw = conf.route.route(dst)
return IPField.i2h(self, pkt, x)
class ByteField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "B")
class XByteField(ByteField):
def i2repr(self, pkt, x):
if x is None:
return hex(self.i2h(pkt, x))
class X3BytesField(XByteField):
def __init__(self, name, default):
Field.__init__(self, name, default, "I")
def addfield(self, pkt, s, val):
return s+struct.pack(self.fmt, self.i2m(pkt,val))[:3]
def getfield(self, pkt, s):
s[3:], self.m2i(pkt, struct.unpack(self.fmt, "\x00"+s[:3])[0])
class ShortField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "H")
class LEShortField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "@H")
class XShortField(ShortField):
def i2repr(self, pkt, x):
if x is None:
return hex(self.i2h(pkt, x))
class IntField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "I")
class LEIntField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "@I")
class XIntField(IntField):
def i2repr(self, pkt, x):
if x is None:
return hex(self.i2h(pkt, x))
class LongField(Field):
def __init__(self, name, default):
Field.__init__(self, name, default, "Q")
class XLongField(LongField):
def i2repr(self, pkt, x):
if x is None:
return hex(self.i2h(pkt, x))
class StrField(Field):
def __init__(self, name, default, fmt="H", remain=0):
Field.__init__(self,name,default,fmt)
self.remain = remain
def i2m(self, pkt, x):
if x is None:
def addfield(self, pkt, s, val):
return s+self.i2m(pkt, val)
def getfield(self, pkt, s):
if self.remain == 0:
return "",self.m2i(pkt, s)
return s[-self.remain:],self.m2i(pkt, s[:-self.remain])
class PacketField(StrField):
def __init__(self, name, default, cls):
StrField.__init__(self, name, default)
self.cls = cls
def i2m(self, pkt, i):
return str(i)
def m2i(self, pkt, m):
return self.cls(m)
def getfield(self, pkt, s):
i = self.m2i(pkt, s)
remain = ""
if i.haslayer(Padding):
r = i.getlayer(Padding)
del(r.underlayer.payload)
remain = r.load
return remain,i
class PacketLenField(PacketField):
def __init__(self, name, default, cls, fld):
PacketField.__init__(self, name, default, cls)
self.fld = fld
def getfield(self, pkt, s):
l = getattr(pkt, self.fld)
l += pkt.fields_desc[pkt.fields_desc.index(self.fld)].shift
i = self.m2i(pkt, s[:l])
return s[l:],i
class StrFixedLenField(StrField):
def __init__(self, name, default, length):
StrField.__init__(self, name, default)
self.length = length
def getfield(self, pkt, s):
return s[self.length:], self.m2i(pkt,s[:self.length])
def addfield(self, pkt, s, val):
return s+struct.pack("%ss"%self.length,self.i2m(pkt, val))
class NetBIOSNameField(StrFixedLenField):
def __init__(self, name, default, length=31):
StrFixedLenField.__init__(self, name, default, length)
def i2m(self, pkt, x):
if x is None:
x += " "*(self.length/2-1)
x = x[:(self.length/2-1)]
x = "".join(map(lambda x: chr(0x41+(ord(x)>>4))+chr(0x41+(ord(x)&0xf)), x))
def m2i(self, pkt, x):
x = x.strip("\x00").strip(" ")
return "".join(map(lambda x,y: chr((((ord(x)-1)&0xf)<<4)+((ord(y)-1)&0xf)), x[::2],x[1::2]))
class StrLenField(StrField):
def __init__(self, name, default, fld):
StrField.__init__(self, name, default)
self.fld = fld
def getfield(self, pkt, s):
l = getattr(pkt, self.fld)
# add the shift from the length field
f = pkt.fields_desc[pkt.fields_desc.index(self.fld)]
if isinstance(f, FieldLenField):
l += f.shift
return s[l:], self.m2i(pkt,s[:l])
class FieldLenField(Field):
def __init__(self, name, default, fld, fmt = "H", shift=0):
Field.__init__(self, name, default, fmt)
self.fld = fld
self.shift = shift
def i2m(self, pkt, x):
if x is None:
f = pkt.fields_desc[pkt.fields_desc.index(self.fld)]
v = f.i2m(pkt,getattr(pkt, self.fld))
x = len(v)-self.shift
def i2h(self, pkt, x):
if x is None:
f = pkt.fields_desc[pkt.fields_desc.index(self.fld)]
v = f.i2m(pkt,getattr(pkt, self.fld))
x = len(v)+self.shift
ISAKMPTransformTypes = { "Encryption":
(1, { "DES-CBS"
"3DES-CBC" : 5, }),
(2, { "MD5": 1,
"SHA": 2, }),
"Authentication":(3, { "PSK": 1, }),
"GroupDesc":
(4, { "768MODPgr"
"1024MODPgr" : 2, }),
"LifeType":
(11,{ "Seconds":1, }),
"LifeDuration":
ISAKMPTransformNum = {}
for n in ISAKMPTransformTypes:
val = ISAKMPTransformTypes[n]
for e in val[1]:
tmp[val[1][e]] = e
ISAKMPTransformNum[val[0]] = (n,tmp)
class ISAKMPTransformSetField(StrLenField):
def type2num(self, (typ,enc)):
if ISAKMPTransformTypes.has_key(typ):
val = ISAKMPTransformTypes[typ]
val = (int(typ),{})
if val[1].has_key(enc):
enc = val[1][enc]
enc = int(enc)
return ((val[0] | 0x8000L) <> 16) & 0x7fff
enc = num & 0xffff
val = ISAKMPTransformNum.get(typ,(typ,{}))
enc = val[1].get(enc,enc)
return (val[0],enc)
def i2m(self, pkt, i):
if i is None:
i = map(self.type2num, i)
return struct.pack("!"+"I"*len(i),*i)
def m2i(self, pkt, m):
lst = struct.unpack("!"+"I"*(len(m)/4),m)
lst = map(self.num2type, lst)
return lst
def getfield(self, pkt, s):
l = getattr(pkt, self.fld)
l += pkt.fields_desc[pkt.fields_desc.index(self.fld)].shift
i = self.m2i(pkt, s[:l])
return s[l:],i
class StrNullField(StrField):
def addfield(self, pkt, s, val):
return s+self.i2m(pkt, val)+"\x00"
def getfield(self, pkt, s):
l = s.find("\x00")
#XXX \x00 not found
return "",s
return s[l+1:],self.m2i(pkt, s[:l])
class StrStopField(StrField):
def __init__(self, name, default, stop, additionnal=0):
Field.__init__(self, name, default)
self.stop=stop
self.additionnal=additionnal
def getfield(self, pkt, s):
l = s.find(self.stop)
return "",s
raise Exception,"StrStopField: stop value [%s] not found" %stop
l += len(self.stop)+self.additionnal
return s[l:],s[:l]
class LenField(Field):
def i2m(self, pkt, x):
if x is None:
x = len(pkt.payload)
class BCDFloatField(Field):
def i2m(self, pkt, x):
return int(256*x)
def m2i(self, pkt, x):
return x/256.0
class BitField(Field):
def __init__(self, name, default, size):
Field.__init__(self, name, default)
self.size = size
def addfield(self, pkt, s, val):
if val is None:
if type(s) is tuple:
s,bitsdone,v = s
bitsdone = 0
v <<= self.size
v |= val & ((1L<= 8:
bitsdone -= 8
s = s+struct.pack("!B", v >> bitsdone)
v &= (1L<<bitsdone)-1
if bitsdone:
return s,bitsdone,v
def getfield(self, pkt, s):
if type(s) is tuple:
# we don't want to process all the string
nb_bytes = (self.size+bn-1)/8 + 1
w = s[:nb_bytes]
# split the substring byte by byte
bytes = struct.unpack('!%dB' % nb_bytes , w)
for c in range(nb_bytes):
b |= long(bytes[c]) << (nb_bytes-c-1)*8
# get rid of high order bits
b &= (1L <> (nb_bytes*8 - self.size - bn)
bn += self.size
s = s[bn/8:]
return (s,bn),b
return s,b
class XBitField(BitField):
def i2repr(self, pkt, x):
return hex(self.i2h(pkt,x))
class EnumField(Field):
def __init__(self, name, default, enum, fmt = "H"):
Field.__init__(self, name, default, fmt)
i2s = self.i2s = {}
s2i = self.s2i = {}
if type(enum) is list:
keys = xrange(len(enum))
keys = enum.keys()
if filter(lambda x: type(x) is str, keys):
i2s,s2i = s2i,i2s
for k in keys:
i2s[k] = enum[k]
s2i[enum[k]] = k
def any2i(self, pkt, x):
if type(x) is str:
x = self.s2i[x]
def i2repr(self, pkt, x):
return self.i2s.get(x, x)
class BitEnumField(BitField,EnumField):
def __init__(self, name, default, size, enum):
EnumField.__init__(self, name, default, enum)
self.size = size
def any2i(self, pkt, x):
return EnumField.any2i(self, pkt, x)
def i2repr(self, pkt, x):
return EnumField.i2repr(self, pkt, x)
class ShortEnumField(EnumField):
def __init__(self, name, default, enum):
EnumField.__init__(self, name, default, enum, "H")
class LEShortEnumField(EnumField):
def __init__(self, name, default, enum):
EnumField.__init__(self, name, default, enum, "@H")
class ByteEnumField(EnumField):
def __init__(self, name, default, enum):
EnumField.__init__(self, name, default, enum, "B")
class IntEnumField(EnumField):
def __init__(self, name, default, enum):
EnumField.__init__(self, name, default, enum, "I")
class LEIntEnumField(EnumField):
def __init__(self, name, default, enum):
EnumField.__init__(self, name, default, enum, "@I")
class XShortEnumField(ShortEnumField):
def i2repr(self, pkt, x):
return self.i2s.get(x, hex(x))
class FlagsField(BitField):
def __init__(self, name, default, size, names):
BitField.__init__(self, name, default, size)
self.multi = type(names) is list
if self.multi:
self.names = map(lambda x:[x], names)
self.names = names
def any2i(self, pkt, x):
if type(x) is str:
if self.multi:
x = map(lambda y:[y], x.split("+"))
for i in x:
y |= 1 <>= 1
if self.multi:
r =}

我要回帖

更多关于 iplist 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信