pcs-0.6/0000775000175000017500000000000011256035475011772 5ustar andreasandreaspcs-0.6/pcs/0000775000175000017500000000000011323556441012553 5ustar andreasandreaspcs-0.6/pcs/clock/0000775000175000017500000000000011323556365013653 5ustar andreasandreaspcs-0.6/pcs/clock/clock.pyx0000664000175000017500000000615111255512624015505 0ustar andreasandreas# # bpf.pyx # # $Id$ """Clock module This module provides a Python front-end for POSIX clocks. """ __author__ = 'Bruce M. Simpson ' __maintainer__ = 'Bruce M. Simpson ' __copyright__ = 'Copyright (c) 2008 Bruce M. Simpson' __license__ = 'BSD license' __url__ = 'http://pcs.sf.net' __version__ = '1.0' __revison__ = '0' # Most of these are simply stubbed on Windows, because # supporting them properly requires Vista/Longhorn. ctypedef int clockid_t # POSIX clock IDs CLOCK_REALTIME = 0 CLOCK_VIRTUAL = 1 CLOCK_PROF = 2 CLOCK_MONOTONIC = 4 # FreeBSD-specific clock IDs IF UNAME_SYSNAME == "FreeBSD": CLOCK_UPTIME = 5 CLOCK_UPTIME_PRECISE = 7 CLOCK_UPTIME_FAST = 8 CLOCK_REALTIME_PRECISE = 9 CLOCK_REALTIME_FAST = 10 CLOCK_MONOTONIC_PRECISE = 11 CLOCK_MONOTONIC_FAST = 12 CLOCK_SECOND = 13 cdef extern from "time.h": struct timespec: unsigned int tv_sec long tv_nsec cdef extern from "time.h": int clock_gettime(clockid_t clock_id, timespec *tp) int clock_settime(clockid_t clock_id, timespec *tp) int clock_getres(clockid_t clock_id, timespec *tp) def gettime(clockid_t clock_id): """Get the time kept by a POSIX clock. Return float or None.""" IF UNAME_SYSNAME == "Windows": return None ELSE: cdef timespec t cdef int rc cdef double result rc = clock_gettime(clock_id, &t) if rc != 0: return None result = _timespec_to_double(&t) return result # implicit conversion C double->Python Float def settime(clockid_t clock_id, double value): """Set the time for a POSIX clock. Return boolean success.""" IF UNAME_SYSNAME == "Windows": return False ELSE: cdef timespec t cdef int rc # implicit conversion Python float->C double _double_to_timespec(value, &t) rc = clock_settime(clock_id, &t) return bool(rc == 0) def getres(clockid_t clock_id): """Get the resolution of a POSIX clock. Return float or None.""" IF UNAME_SYSNAME == "Windows": return None ELSE: cdef timespec t cdef int rc cdef double result rc = clock_getres(clock_id, &t) if rc != 0: return None result = _timespec_to_double(&t) return result # This looks gnarly. We need to preserve the precision of the POSIX # timespec, but doing this needs to be somewhat munged to use plain # C arithmetic in Pyrex syntax. cdef void _double_to_timespec(double f, timespec *tp): """Convert a double to a normalized timespec.""" tp[0].tv_sec = f tp[0].tv_nsec = ((f - (tp[0].tv_nsec)) * 1000000000 + 0.5e-9) if tp[0].tv_nsec >= 1000000000: tp[0].tv_sec = tp[0].tv_sec + (tp[0].tv_nsec / 1000000000) tp[0].tv_nsec = tp[0].tv_nsec % 1000000000 cdef double _timespec_to_double(timespec *tp): """Convert a normalized timespec to a double.""" cdef double result result = tp[0].tv_sec * 1.0 result = result + (tp[0].tv_nsec * 1.0e-9) return result pcs-0.6/pcs/packets/0000775000175000017500000000000011323556365014212 5ustar andreasandreaspcs-0.6/pcs/packets/localhost.py0000664000175000017500000000504311255512624016550 0ustar andreasandreas# Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: localhost.py,v 1.1 2006/07/04 13:30:10 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A packet to handle localhost encoded tcpdump packets. import socket import pcs from pcs.packets import ipv4 from pcs.packets import ipv6 import localhost_map import inspect import time class localhost(pcs.Packet): """Localhost""" _layout = pcs.Layout() _map = localhost_map.map def __init__(self, bytes = None, timestamp = None, **kv): """initialize a localhost header, needed to read or write to lo0""" type = pcs.Field("type", 32, discriminator=True) lolen = 4 pcs.Packet.__init__(self, [type], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[lolen:len(bytes)], timestamp = timestamp) else: self.data = None pcs-0.6/pcs/packets/localhost_map.py0000664000175000017500000000434211255512624017406 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: This is a module which maps Ethernet protocol types to # class names for use by the Ethernet class. # The map is a dictionary who's key is the protocol type and who's # value is the class constructor for that type. import ipv4, ipv6, socket # Loopback (localhost) interfaces are a bit funky. The type is in # HOST byte order, not network byte order so depending on where a pcap # file was recorded the bytes may be in big or little endian order, # hence the following set of double entries. map = {socket.AF_INET: ipv4.ipv4, socket.AF_INET6: ipv6.ipv6, socket.ntohl(socket.AF_INET): ipv4.ipv4, socket.ntohl(socket.AF_INET6): ipv6.ipv6} pcs-0.6/pcs/packets/vlan.py0000664000175000017500000000531211255512624015517 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe IEEE 802.1q VLAN headers. # import inspect import struct import time import pcs import pcs.packets.ethernet_map import pcs.packets.payload class vlan(pcs.Packet): """IEEE 802.1q VLAN header""" _layout = pcs.Layout() _map = ethernet_map.map def __init__(self, bytes = None, timestamp = None, **kv): type = pcs.Field("type", 16) p = pcs.Field("p", 3) cfi = pcs.Field("cfi", 1) # Canonical MAC vlan = pcs.Field("vlan", 12) pcs.Packet.__init__(self, [ type, p, cfi, vlan ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset self.data = self.next(bytes[curr:remaining], timestamp=timestamp) if bytes is not None: self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None pcs-0.6/pcs/packets/ipv4.py0000664000175000017500000002521111255512624015441 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ipv4.py,v 1.6 2006/09/05 07:30:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class which implements an IPv4 packet import pcs from pcs import UnpackError from socket import AF_INET, inet_ntop import ipv4_map import struct import inspect import time # # IPv4 address constants. # INADDR_ANY = 0x00000000 # 0.0.0.0 INADDR_NONE = 0x00000000 # 0.0.0.0 INADDR_BROADCAST = 0xffffffff # 255.255.255.255 INADDR_LOOPBACK = 0x7f000001 # 127.0.0.1 INADDR_UNSPEC_GROUP = 0xe0000000 # 224.0.0.0 INADDR_ALLHOSTS_GROUP = 0xe0000001 # 224.0.0.1 INADDR_ALLRTRS_GROUP = 0xe0000002 # 224.0.0.2 INADDR_DVMRP_GROUP = 0xe0000004 # 224.0.0.4 INADDR_ALLPIM_ROUTERS_GROUP = 0xe000000d # 224.0.0.13 INADDR_ALLRPTS_GROUP = 0xe0000016 # 224.0.0.22, IGMPv3 INADDR_MAX_LOCAL_GROUP = 0xe00000ff # 224.0.0.255 # # IPv4 header flags. # IP_MF = 1 # More fragments IP_DF = 2 # Don't fragment IP_RF = 4 # Reserved; always set to 0. # # IPv4 options. # IPOPT_EOL = 0 IPOPT_NOP = 1 IPOPT_RA = 148 def IN_LINKLOCAL(i): """Return True if the given address is in the 169.254.0.0/16 range.""" return (((i) & 0xffff0000) == 0xa9fe0000) def IN_MULTICAST(i): """Return True if the given address is in the 224.0.0.0/4 range.""" return (((i) & 0xf0000000) == 0xe0000000) def IN_LOCAL_GROUP(i): """Return True if the given address is in the 224.0.0.0/24 range.""" return (((i) & 0xffffff00) == 0xe0000000) def IN_EXPERIMENTAL(i): """Return True if the given address is in the 240.0.0.0/24 range.""" return (((i) & 0xf0000000) == 0xf0000000) def IN_PRIVATE(i): """Return True if the given address is in any of the 10.0.0.0/8, 172.16.0.0/16, or 192.168.0.0/24 ranges from RFC 1918.""" return ((((i) & 0xff000000) == 0x0a000000) or \ (((i) & 0xfff00000) == 0xac100000) or \ (((i) & 0xffff0000) == 0xc0a80000)) class ipv4opt(pcs.TypeLengthValueField): """Syntactic sugar for IPv4 option use in constructors. XXX Currently only Router Alert is supported properly. """ def __init__(self, type, **kv): pcs.TypeLengthValueField.__init__(self, "", \ pcs.Field("", 8, default = type), \ pcs.Field("", 8), \ pcs.Field("", 16)) # XXX class ipv4(pcs.Packet): """IPv4""" _layout = pcs.Layout() _map = ipv4_map.map def __init__(self, bytes = None, timestamp = None, **kv): """ define the fields of an IPv4 packet, from RFC 791.""" version = pcs.Field("version", 4, default=4) hlen = pcs.Field("hlen", 4, default=5) tos = pcs.Field("tos", 8) length = pcs.Field("length", 16, default=20) id = pcs.Field("id", 16) flags = pcs.Field("flags", 3) offset = pcs.Field("offset", 13, default=0) ttl = pcs.Field("ttl", 8, default=64) protocol = pcs.Field("protocol", 8, discriminator=True) checksum = pcs.Field("checksum", 16) src = pcs.Field("src", 32) dst = pcs.Field("dst", 32) options = pcs.OptionListField("options") pcs.Packet.__init__(self, [version, hlen, tos, length, id, flags, offset, ttl, protocol, checksum, src, dst, options], bytes = bytes, **kv) # Description MUST be set after the PCS layer init self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: hlen_bytes = self.hlen * 4 options_len = hlen_bytes - self.sizeof() if hlen_bytes > len(bytes): raise UnpackError, \ "IP header is larger than input (%d > %d)" % \ (hlen_bytes, len(bytes)) if options_len > 0: curr = self.sizeof() while curr < hlen_bytes: option = struct.unpack('!B', bytes[curr])[0] if option == IPOPT_EOL: options.append(pcs.Field("end", 8, default = IPOPT_EOL)) curr += 1 continue elif option == IPOPT_NOP: options.append(pcs.Field("nop", 8, default = IPOPT_NOP)) curr += 1 continue optlen = struct.unpack('!B', bytes[curr+1])[0] if option == IPOPT_RA: # The IPv4 Router Alert option (RFC 2113) is a # single 16 bit value. Its existence indicates # that a router must examine the packet. It is # 32 bits wide including option code and length. if optlen != 4: raise UnpackError, \ "Bad length %d for IP option %d, " \ "should be %d" % (optlen, option, 4) value = struct.unpack("!H", bytes[curr+2:curr+4])[0] options.append(pcs.TypeLengthValueField("ra", pcs.Field("t", 8, default = option), pcs.Field("l", 8, default = optlen), pcs.Field("v", 16, default = value))) curr += optlen else: print "warning: unknown IP option %d" % option optdatalen = optlen - 2 options.append(pcs.TypeLengthValueField("unknown", pcs.Field("t", 8, default = option), pcs.Field("l", 8, default = optlen), pcs.Field("v", optdatalen * 8, default = value))) curr += optlen if (bytes is not None): offset = self.hlen << 2 self.data = self.next(bytes[offset:len(bytes)], timestamp = timestamp) if self.data is None: from pcs.packets.payload import payload self.data = payload(bytes[offset:len(bytes)]) #if __debug__: # print "decoded IPv4 payload proto", self.protocol, "as", type(self.data) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" retval = "IPv4\n" for fn in self._layout: f = self._fieldnames[fn.name] if (fn.name == "src" or fn.name == "dst"): value = inet_ntop(AF_INET, struct.pack('!L', f.value)) retval += "%s %s\n" % (fn.name, value) else: retval += "%s %s\n" % (fn.name, f.value) return retval def pretty(self, attr): if attr == "src" or attr == "dst": return inet_ntop(AF_INET, struct.pack('!L', getattr(self,attr))) def calc_checksum(self): """Calculate and store the checksum for this packet.""" #print "ipv4.calc_checksum()" self.checksum = 0 self.checksum = ipv4.ipv4_cksum(self.getbytes()) def calc_length(self): """Calculate and store the length field(s) for this packet.""" tmpbytes = self.getbytes() self.hlen = (len(tmpbytes) >> 2) self.length = len(tmpbytes) if self._head is not None: self.length += len(self._head.collate_following(self)) def ipv4_cksum(bytes): """Static method to: Calculate and return the IPv4 header checksum over the string of bytes provided.""" tmpbytes = bytes total = 0 if len(tmpbytes) % 2 == 1: tmpbytes += "\0" for i in range(len(tmpbytes)/2): total += (struct.unpack("!H", tmpbytes[2*i:2*i+2])[0]) total = (total >> 16) + (total & 0xffff) total += total >> 16 return ~total & 0xffff ipv4_cksum = staticmethod(ipv4_cksum) # # Convenience object for higher level protocols that need a fake IPv4 # header to calculate a checksum. class pseudoipv4(pcs.Packet): """IPv4 Pseudo Header""" _layout = pcs.Layout() _map = None from socket import IPPROTO_TCP def __init__(self, bytes = None, timestamp = None, proto = IPPROTO_TCP): """For a pseudo header we only need the source and destination ddresses.""" src = pcs.Field("src", 32) dst = pcs.Field("dst", 32) reserved = pcs.Field("reserved", 8, default = 0) protocol = pcs.Field("protocol", 8, default = proto) length = pcs.Field("length", 16) pcs.Packet.__init__(self, [src, dst, reserved, protocol, length], bytes = bytes) # Description MUST be set after the PCS layer init self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp self.data = None pcs-0.6/pcs/packets/tcpv6.py0000664000175000017500000001121511255512624015620 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: tcpv6.py,v 1.1 2006/07/06 09:31:57 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class that describes a TCP packet for IPv6. import pcs import struct import pcs.packets.ipv4 from pcs.packets.pseudoipv6 import * import inspect import time class tcpv6(pcs.Packet): """TCPv6""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize a TCP packet for IPv6""" sport = pcs.Field("sport", 16) dport = pcs.Field("dport", 16) seq = pcs.Field("sequence", 32) acknum = pcs.Field("ack_number", 32) off = pcs.Field("offset", 4) reserved = pcs.Field("reserved", 6) urg = pcs.Field("urgent", 1) ack = pcs.Field("ack", 1) psh = pcs.Field("push", 1) rst = pcs.Field("reset", 1) syn = pcs.Field("syn", 1) fin = pcs.Field("fin", 1) window = pcs.Field("window", 16) cksum = pcs.Field("checksum", 16) urgptr = pcs.Field("urg_pointer", 16) pcs.Packet.__init__(self, [sport, dport, seq, acknum, off, reserved, urg, ack, psh, rst, syn, fin, window, cksum, urgptr], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp def __str__(self): """Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0.""" retval = "" for field in self._layout: if (field.type == str): retval += "%s %s\n" % (field.name, field.value) else: retval += "%s %d\n" % (field.name, field.value) return retval def cksum(self, ip, data = "", nx = 0): """Calculate checksum over TCP v6 segment outside of a chain.""" total = 0 p6 = pseudoipv6() p6.src = ip.src p6.dst = ip.dst p6.length = len(self.getbytes()) + len (data) if nx: p6.next_header = nx else: p6.next_header = ip.next_header pkt = p6.getbytes() + self.getbytes() + data return ipv4.ipv4_cksum(pkt) def calc_checksum(self): """Calculate and store the checksum for this TCP v6 segment. The packet must be part of a chain. To do this we need to use an overlay, and copy some header fields from the encapsulating IPv6 header.""" self.checksum = 0 if self._head is not None: payload = self._head.collate_following(self) ip6 = self._head.find_preceding(self, pcs.packets.ipv6) assert ip6 is not None, "No preceding IPv6 header." pip6 = pseudoipv6() pip6.src = ip.src pip6.dst = ip.dst pip6.next_header = ip6.next_header pip6.length = len(self.getbytes()) + len(payload) tmpbytes = pip6.getbytes() + self.getbytes() + payload else: tmpbytes = self.bytes self.checksum = ipv4.ipv4_cksum(tmpbytes) pcs-0.6/pcs/packets/mpls.py0000664000175000017500000001206211255512624015532 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe Multiprotocol Label Switching (MPLS) # import inspect import struct import time import pcs import pcs.packets.payload # # Default labels # LABEL_IPV4_NULL = 0 LABEL_ROUTER_ALERT = 1 LABEL_IPV6_NULL = 2 LABEL_NULL = 3 # # LDP TLV: U:1 F:1 type: 13 len: 16 # TODO: format. # LDP_TLV_FEC = 0x0100 LDP_TLV_ADDRESSES = 0x0101 LDP_TLV_HOPCOUNT = 0x0103 LDP_TLV_PATHVEC = 0x0104 LDP_TLV_LABEL = 0x0200 LDP_TLV_ATM = 0x0201 LDP_TLV_FR = 0x0202 LDP_TLV_STATUS = 0x0300 # # FEC TLV elements # FEC_ELEM_PREFIX = 2 FEC_ELEM_HOST = 3 # # Message types # LDP_MSG_NOTIFY = 0x0001 LDP_MSG_HELLO = 0x0100 LDP_MSG_INIT = 0x0200 LDP_MSG_KEEPALIVE = 0x0201 LDP_MSG_ADDR_ANNOUNCE = 0x0300 LDP_MSG_ADDR_WITHDRAW = 0x0301 LDP_MSG_MAPPING = 0x0400 LDP_MSG_REQUEST = 0x0401 LDP_MSG_WITHDRAW = 0x0402 LDP_MSG_RELEASE = 0x0403 LDP_MSG_ABORT = 0x0404 class ldpmsg(pcs.Packet): """RFC 3036 LDP message header """ _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): u = pcs.Field("u", 1) type = pcs.Field("exp", 15) length = pcs.Field("length", 16) id = pcs.Field("id", 32) mparams = pcs.OptionListField("") oparams = pcs.OptionListField("") pcs.Packet.__init__(self, [ u, type, length, id, mparams, oparams ], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None class ldphdr(pcs.Packet): """RFC 3036 LDP packet header """ _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): version = pcs.Field("label", 16) length = pcs.Field("exp", 16) id = pcs.StringField("id", 48) pcs.Packet.__init__(self, [ version, length, id ], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None class lse(pcs.Packet): """RFC 3032 MPLS label stack entry""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): label = pcs.Field("label", 20) exp = pcs.Field("exp", 3) s = pcs.Field("s", 1) ttl = pcs.Field("ttl", 8) pcs.Packet.__init__(self, [ label, exp, s, ttl ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None pcs-0.6/pcs/packets/udp_map.py0000664000175000017500000000332611255512624016207 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: DNS = 53 BOOTPS = 67 BOOTPC = 68 import dns import dhcpv4 map = { DNS: dns.dnsheader, BOOTPS: dhcpv4.dhcpv4, BOOTPC: dhcpv4.dhcpv4 } pcs-0.6/pcs/packets/netlink.py0000664000175000017500000001643611255512624016234 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe RFC 3549 Netlink socket messages. # import inspect import struct import time import pcs import payload # TODO: Test all this. # TODO: add AF_NETLINK, PF_NETLINK and struct sockaddr_nl where needed. # Socket options; not yet needed. #NETLINK_ADD_MEMBERSHIP = 1 #NETLINK_DROP_MEMBERSHIP = 2 #NETLINK_PKTINFO = 3 # returns a uint32_t (group) # # Netlink link types. # # Netlink is a full-blown socket address family, so the subsystem(s) # which send messages will have a sockaddr filled out. # Currently this module only supports the routing messages. # NETLINK_ROUTE = 0 # nlmsg_type NLMSG_NOOP = 0x1 NLMSG_ERROR = 0x2 NLMSG_DONE = 0x3 # end of multipart. NLMSG_OVERRUN = 0x4 # unused? # nlmsg_flags NLM_F_REQUEST = 1 NLM_F_MULTI = 2 NLM_F_ACK = 4 NLM_F_ECHO = 8 NLM_F_ROOT = 0x100 NLM_F_MATCH = 0x200 NLM_F_DUMP = 0x300 # or'd NLM_F_ATOMIC = 0x400 NLM_F_REPLACE = 0x100 NLM_F_EXCL = 0x200 NLM_F_CREATE = 0x400 NLM_F_APPEND = 0x800 # TODO: nlattr tlvs. NLA_F_NESTED = 0x8000 NLA_F_NET_BYTEORDER = 0x4000 class nlmsg_error(pcs.Packet): """If type is NLMSG_ERROR, original message generating error is returned as payload with error code prepended, just like ICMP.""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): error = pcs.Field("error", 32) pcs.Packet.__init__(self, [error], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # XXX To avoid introducing a circular dependency in this module, # the caller is responsible for trying to decode the payload # as an nlmsghdr chain. if bytes is not None: self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None # XXX Move these to a separate file. The map needs to live outside # to avoid circular dependencies, and to make it easier to # introduce parsers for dealing with subsystems e.g. rtnetlink. nlmsg_map = { NLMSG_NOOP: payload.payload, NLMSG_ERROR: nlmsg_error } descr = { NLMSG_NOOP: "Noop", NLMSG_ERROR: "Error" } # XXX Can't fully discriminate without knowing which subsystem # the message was sent from. class nlmsghdr(pcs.Packet): """RFC 3549 Netlink socket message header.""" _layout = pcs.Layout() #_map = nlmsg_map #_descr = descr _map = nlmsg_map _descr = descr # Python string literals for bsprintf() need to contain hex # embedded characters. _flag_bits = "\x01REQUEST\x02MULTI\x03ACK\x04ECHO"\ "\x09ROOT\x0aMATCH\x0bATOMIC"\ "\x0dREPLACE\x0eEXCL\x0fCREATE"\ "\x10APPEND" def __init__(self, bytes = None, timestamp = None, **kv): """ Define the common Netlink message header.""" len = pcs.Field("len", 32) type = pcs.Field("type", 16, discriminator=True) flags = pcs.Field("flags", 16) seq = pcs.Field("seq", 32) pid = pcs.Field("pid", 32) # Port ID pcs.Packet.__init__(self, [len, type, flags, seq, pid], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() # XXX Check and use the length field. remaining = min(len(bytes), self.len) - offset if remaining < 0: remaining = len(bytes) # Only use the external map to look up the payload type # if it isn't of a type we know about. if self._fieldnames['type'].value == NLMSG_ERROR: self.data = nlmsg_error(bytes[offset:remaining], \ timestamp=timestamp) elif (self._fieldnames['type'].value != NLMSG_NOOP) and \ (self._fieldnames['type'].value != NLMSG_DONE): self.data = self.next(bytes[offset:remaining], \ timestamp=timestamp) # If we failed to look up a payload type, assume that # the payload is opaque. if self.data is None: self.data = payload.payload(bytes[offset:remaining], \ timestamp=timestamp) else: self.data = None # XXX TODO: fit rtnetlink in here. def next(self, bytes, timestamp): """Decode next layer of encapsulation.""" #if (self.dport in udp_map.map): # return udp_map.map[self.dport](bytes, timestamp = timestamp) #if (self.sport in udp_map.map): # return udp_map.map[self.sport](bytes, timestamp = timestamp) return None # XXX TODO: fit rtnetlink in here. def rdiscriminate(self, packet, discfieldname=None, map = nlmsg_map): """Reverse-map an encapsulated packet back to a discriminator field value. Like next() only the first match is used.""" # XXX The type field MAY have meaning which is specific to # the group where this Netlink format message came from. return pcs.Packet.rdiscriminate(self, packet, "type", map) def __str__(self): """Pretty-print fields.""" s = "Netlink\n" #s = "Netlink " + self._descr[self._fieldnames['type']] + "\n" for fn in self._layout: f = self._fieldnames[fn.name] if fn.name == "flags": value = bsprintf(f.value, self._flag_bits) s += "%s %s\n" % (fn.name, value) else: s += "%s %s\n" % (fn.name, f.value) return s #def calc_lengths(self): pcs-0.6/pcs/packets/ieee8021d.py0000664000175000017500000001363411255512624016153 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe IEEE 802.1d and GARP headers. # import inspect import struct import time import pcs import pcs.packets.payload # # How you tell GMRP and GVRP apart. # ETHER_DEST_GMRP = "\x01\x80\xc2\x00\x00\x20" ETHER_DEST_GVRP = "\x01\x80\xc2\x00\x00\x21" PROTO_STP = 0x0000 PROTO_GARP = 0x0001 # TODO: GARP, GMRP and GVRP TLVs. ATTR_END = 0 ATTR_GROUP = 1 ATTR_VID = ATTR_GROUP # Alias for GVRP ATTR_REQUIREMENT = 2 # GARP attribute event types EVENT_LEAVE_ALL = 0 EVENT_JOIN_EMPTY = 1 EVENT_JOIN_IN = 2 EVENT_LEAVE_EMPTY = 3 EVENT_LEAVE_IN = 4 EVENT_EMPTY = 5 # GARP message: 1byte attribute type + 1..N attribute + end mark # lengths are inclusive: # GARP attribute TLV: 1/1/n length/event/value # GVRP attribute TLV: 1/1/2 length/event/vlanid class garp(pcs.Packet): """IEEE 802.1d GARP PDU""" def __init__(self, bytes = None, timestamp = None, **kv): attributes = pcs.OptionListField("attributes") pcs.Packet.__init__(self, [ attributes ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset # TODO parse GARP attribute list.. if self.data is None: self.data = payload.payload(bytes[curr:remaining], \ timestamp=timestamp) else: self.data = None class stp(pcs.Packet): """IEEE 802.1d STP PDU""" _layout = pcs.Layout() _flagbits = "\x01ACK\x02AGREE\x03FORWARDING\x04LEARNING\x05BACKUP" \ "\x06ROOT\x07PROPOSAL\x08CHANGED" def __init__(self, bytes = None, timestamp = None, **kv): version = pcs.Field("version", 8) type = pcs.Field("type", 8) flags = pcs.Field("flags", 8) root = pcs.StringField("root", 8 * 8) cost = pcs.Field("cost", 32) src = pcs.StringField("src", 8 * 8) pid = pcs.Field("pid", 16) age = pcs.Field("age", 16) maxage = pcs.Field("maxage", 16) interval = pcs.Field("interval", 16) delay = pcs.Field("delay", 16) #opt = pcs.OptionListField("opt") pcs.Packet.__init__(self, [ version, type, flags, root, \ cost, src, pid, age, maxage, interval, \ delay ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset # 802.1d shouldn't have any trailers. self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" s = self._descr[self.type] + "\n" for fn in self._layout: f = self._fieldnames[fn.name] if fn.name == "flags": bs = bsprintf(f.value, self._flagbits) s += "%s %s\n" % (fn.name, bs) else: s += "%s %s\n" % (fn.name, f.value) return s map = { PROTO_STP: stp, PROTO_GARP: garp } class bpdu(pcs.Packet): """IEEE 802.1d bridge PDU header""" _layout = pcs.Layout() _map = map def __init__(self, bytes = None, timestamp = None, **kv): protocol = pcs.Field("protocol", 16, discriminator=True) pcs.Packet.__init__(self, [ protocol ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset self.data = self.next(bytes[curr:remaining], timestamp=timestamp) if self.data is None: self.data = payload.payload(bytes[curr:remaining], \ timestamp=timestamp) else: self.data = None pcs-0.6/pcs/packets/icmpv6.py0000664000175000017500000002057711255512624015775 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: icmpv6.py,v 1.8 2006/08/30 02:10:40 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class which describes an ICMPv6 packet import pcs import pcs.packets.pseudoipv6 import pcs.packets.ipv4 import struct # icmp6 type ND_ROUTER_SOLICIT = 133 ND_ROUTER_ADVERT = 134 ND_NEIGHBOR_SOLICIT = 135 ND_NEIGHBOR_ADVERT = 136 ND_REDIRECT = 137 MLD6_LISTENER_QUERY = 130 MLD6_LISTENER_REPORT = 131 MLD6_LISTENER_DONE = 132 MLD6_MTRACE_RESP = 200 MLD6_MTRACE = 201 ICMP6_ROUTER_RENUMBERING = 138 ICMP6_NI_QUERY = 139 ICMP6_NI_REPLY = 140 ICMP6_WRUREQUEST = 139 ICMP6_WRUREPLY = 140 ICMP6_DST_UNREACH = 1 ICMP6_PACKET_TOO_BIG = 2 ICMP6_TIME_EXCEEDED = 3 ICMP6_PARAM_PROB = 4 ICMP6_ECHO_REQUEST = 128 ICMP6_ECHO_REPLY = 129 # router renumbering flags ICMP6_RR_FLAGS_TEST = 0x80 ICMP6_RR_FLAGS_REQRESULT = 0x40 ICMP6_RR_FLAGS_FORCEAPPLY = 0x20 ICMP6_RR_FLAGS_SPECSITE = 0x10 ICMP6_RR_FLAGS_PREVDONE = 0x08 class icmpv6(pcs.Packet): _layout = pcs.Layout() def __init__(self, type = 0, bytes = None, **kv): """icmpv6 header RFC2463 and RFC2461""" ty = pcs.Field("type", 8, default = type) code = pcs.Field("code", 8) cksum = pcs.Field("checksum", 16) if type == ICMP6_ECHO_REQUEST or type == ICMP6_ECHO_REPLY: id = pcs.Field("id", 16) seq = pcs.Field("sequence", 16) pcs.Packet.__init__(self, [ty, code, cksum, id, seq], bytes, **kv) elif type == ICMP6_TIME_EXCEEDED or type == ICMP6_DST_UNREACH or type == ND_ROUTER_SOLICIT: unused = pcs.Field("unused", 32) pcs.Packet.__init__(self, [ty, code, cksum, unused], bytes, **kv) elif type == ICMP6_PARAM_PROB: pointer = pcs.Field("pointer", 32) pcs.Packet.__init__(self, [ty, code, cksum, pointer], bytes, **kv) elif type == ICMP6_PACKET_TOO_BIG: mtu = pcs.Field("mtu", 32) pcs.Packet.__init__(self, [ty, code, cksum, mtu], bytes, **kv) elif type == ICMP6_NI_QUERY or type == ICMP6_NI_REPLY: qtype = pcs.Field("qtype", 16) flags = pcs.Field("flags", 16) nonce = pcs.Field("nonce", 64) pcs.Packet.__init__(self, [ty, code, cksum, qtype, flags, nonce], bytes, **kv) elif type == ND_ROUTER_ADVERT: chp = pcs.Field("current_hop_limit", 8) m = pcs.Field("m", 1) o = pcs.Field("o", 1) unused = pcs.Field("unused", 6) rlf = pcs.Field("router_lifetime", 16) rct = pcs.Field("reachable_time", 32) rtt = pcs.Field("retrans_timer", 32) pcs.Packet.__init__(self, [ty, code, cksum, chp, m, o, unused, rlf, rct, rtt], bytes, **kv) elif type == ND_NEIGHBOR_SOLICIT: reserved = pcs.Field("reserved", 32) target = pcs.StringField("target", 16 * 8) pcs.Packet.__init__(self, [ty, code, cksum, reserved, target], bytes, **kv) elif type == ND_NEIGHBOR_ADVERT: r = pcs.Field("router", 1) s = pcs.Field("solicited", 1) o = pcs.Field("override", 1) reserved = pcs.Field("reserved", 29) target = pcs.StringField("target", 16 * 8) pcs.Packet.__init__(self, [ty, code, cksum, r, s, o, reserved, target], bytes, **kv) elif type == ND_REDIRECT: reserved = pcs.Field("reserved", 32) target = pcs.StringField("target", 16 * 8) dest = pcs.StringField("destination", 16 * 8) pcs.Packet.__init__(self, [ty, code, cksum, reserved, target, dest], bytes, **kv) elif type == MLD6_LISTENER_QUERY or type == MLD6_LISTENER_REPORT or type == MLD6_LISTENER_DONE: md = pcs.Field("maxdelay", 16) reserved = pcs.Field("reserved", 16) mcast = pcs.StringField("mcastaddr", 16 * 8) pcs.Packet.__init__(self, [ty, code, cksum, md, reserved, mcast], bytes, **kv) else: pcs.Packet.__init__(self, [ty, code, cksum], bytes, **kv) def cksum(self, ip, data = "", nx = 0): """Calculate the checksum for this ICMPv6 header, outside of a chain.""" p6 = pseudoipv6.pseudoipv6() p6.src = ip.src p6.dst = ip.dst p6.length = len(self.getbytes()) + len (data) if nx: p6.next_header = nx else: p6.next_header = ip.next_header pkt = p6.getbytes() + self.getbytes() + data return ipv4.ipv4_cksum(pkt) def calc_checksum(self): """Calculate and store the checksum for this ICMPv6 header. ICMPv6 checksums are computed over data payloads and next-headers. The packet must be part of a chain.""" self.checksum = 0 if self._head is not None: payload = self._head.collate_following(self) ip6 = self._head.find_preceding(self, pcs.packets.ipv6) assert ip6 is not None, "No preceding IPv6 header." pip6 = pseudoipv6.pseudoipv6() pip6.src = ip6.src pip6.dst = ip6.dst pip6.next_header = ip6.next_header pip6.length = len(self.getbytes()) + len(payload) tmpbytes = pip6.getbytes() + self.getbytes() + payload else: tmpbytes = self.getbytes() self.checksum = ipv4.ipv4_cksum(tmpbytes) class icmpv6option(pcs.Packet): _layout = pcs.Layout() def __init__(self, type = 0, bytes = None, **kv): """add icmp6 option header RFC2461""" ty = pcs.Field("type", 8, default = type) length = pcs.Field("length", 8) # Source Link-Layer Address. if type == 1: source = pcs.StringField("source", 48) pcs.Packet.__init__(self, [ty, length, source], bytes, **kv) # Target Link-Layer Address elif type == 2: target = pcs.StringField("target", 48) pcs.Packet.__init__(self, [ty, length, target], bytes, **kv) # Prefix Information. elif type == 3: plength = pcs.Field("prefix_length", 8) l = pcs.Field("L", 1) a = pcs.Field("A", 1) reserved1 = pcs.Field("reserved1", 6) vlf = pcs.Field("valid_lifetime", 32) plf = pcs.Field("preferred_lifetime", 32) reserved2 = pcs.Field("reserved2", 32) prefix = pcs.StringField("prefix", 16 * 8) pcs.Packet.__init__(self, [ty, length, plength, l, a, reserved1, vlf, plf, reserved2, prefix], bytes, **kv) # Redirected Header. elif type == 4: reserved = pcs.StringField("reserved", 48) pcs.Packet.__init__(self, [ty, length, reserved], bytes, **kv) # MTU elif type == 5: reserved = pcs.Field("reserved", 16) mtu = pcs.Field("mtu", 32) pcs.Packet.__init__(self, [ty, length, reserved, mtu], bytes, **kv) else: pcs.Packet.__init__(self, [ty, length], bytes, **kv) pcs-0.6/pcs/packets/igmpv3.py0000664000175000017500000003667711255512624016006 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe IGMPv3 messages. # import inspect import pcs import struct import time from pcs.packets import payload from pcs.packets.igmpv2 import * from socket import AF_INET, inet_ntop, inet_ntoa # # IGMPv3 group record types. # IGMP_MODE_IS_INCLUDE = 1 IGMP_MODE_IS_EXCLUDE = 2 IGMP_CHANGE_TO_INCLUDE = 3 IGMP_CHANGE_TO_EXCLUDE = 4 IGMP_ALLOW_NEW_SOURCES = 5 IGMP_BLOCK_OLD_SOURCES = 6 # # Minimum length of an IGMPv3 query. # IGMP_V3_QUERY_MINLEN = 12 class query(pcs.Packet): """IGMPv3 query message.""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize an IGMPv3 query""" group = pcs.Field("group", 32) reserved00 = pcs.Field("reserved00", 4) sbit = pcs.Field("sbit", 1) qrv = pcs.Field("qrv", 3) qqic = pcs.Field("qqic", 8) nsrc = pcs.Field("nsrc", 16) srcs = pcs.OptionListField("sources") # If keyword initializers are present, deal with the syntactic sugar. # query's constructor accepts a list of IP addresses. These need # to be turned into Fields for encoding to work, as they are going # to be stashed into the "sources" OptionListField defined above. if kv is not None: for kw in kv.iteritems(): if kw[0] == 'sources': assert isinstance(kw[1], list) for src in kw[1]: assert isinstance(src, int) srcs.append(pcs.Field("", 32, default=src)) kv.pop('sources') pcs.Packet.__init__(self, [group, reserved00, sbit, qrv, qqic, nsrc, srcs], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # Decode source list if provided. if bytes is not None: sources_len = self.nsrc * 4 query_len = self.sizeof() + sources_len if query_len > len(bytes): raise UnpackError, \ "IGMPv3 query is larger than input (%d > %d)" % \ (query_len, len(bytes)) rem = sources_len curr = self.sizeof() while rem >= 4: src = struct.unpack('I', bytes[curr:curr+4])[0] sources.append(pcs.Field("", 32, default = src)) curr += 4 rem -= 4 if rem > 0: print "WARNING: %d trailing bytes in query." % rem # IGMPv3 queries SHOULD NOT contain ancillary data. If we # do find any, we'll append it to the data member. self.data = payload.payload(bytes[query_len:len(bytes)]) else: self.data = None def calc_length(self): """Calculate and store the length field(s) for this packet. An IGMPv3 query has no auxiliary data; the query counts only the number of sources being queried, which may be 0.""" #self.nsrc = len(self._fieldnames['sources']) # OptionListFields are returned as themselves when accessed as # attributes of the enclosing Packet. self.nsrc = len(self.sources) class GroupRecordField(pcs.CompoundField): """An IGMPv3 group record contains report information about a single IGMPv3 group.""" def __init__(self, name, **kv): self.packet = None self.name = name self.type = pcs.Field("type", 8) self.auxdatalen = pcs.Field("auxdatalen", 8) self.nsources = pcs.Field("nsources", 16) self.group = pcs.Field("group", 32) self.sources = pcs.OptionListField("sources") self.auxdata = pcs.OptionListField("auxdata") # XXX I actually have variable width when I am being encoded, # OptionList deals with this. self.width = self.type.width + self.auxdatalen.width + \ self.nsources.width + self.group.width + \ self.sources.width + self.auxdata.width # If keyword initializers are present, deal with the syntactic sugar. if kv is not None: for kw in kv.iteritems(): if kw[0] in self.__dict__: if kw[0] == 'auxdata': if not isinstance(kw[1], str): if __debug__: print "argument is not a string" continue self.auxdata.append([pcs.StringField("", \ len(kv[1]) * 8, \ default=kv[1])]) elif kw[0] == 'sources': if not isinstance(kw[1], list): if __debug__: print "argument is not a list" continue for src in kw[1]: if not isinstance(src, int): if __debug__: print "source is not an IPv4 address" continue self.sources.append(pcs.Field("", 32, default=src)) else: self.__dict__[kw[0]].value = kw[1] def __repr__(self): return "" \ % (self.type, self.auxdatalen, self.nsources, \ self.group, self.sources, self.auxdata) def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" retval = " GroupRecord\n" retval += "Type %d\n" % self.type.value retval += "Auxdatalen %d\n" % self.auxdatalen.value retval += "Nsources %d\n" % self.nsources.value gs = inet_ntop(AF_INET, struct.pack('!L', self.group.value)) retval += "Group %s\n" % gs retval += "Sources " i = False for s in self.sources._options: if i is False: retval += ", " ss = inet_ntop(AF_INET, struct.pack('!L', s.value)) retval += ss i = True return retval def __setattr__(self, name, value): object.__setattr__(self, name, value) if self.packet is not None: self.packet.__needencode = True # OptionList decode is funny. If you don't have the packet # contents reflected in the PCS representation already, then it will # not produce anything -- the OptionLists are empty. # This is why the TCP and IP option list decoders have to act on # the backing store provided. Similarly we have to do the same here. def decode(self, bytes, curr, byteBR): start = curr [self.type.value, curr, byteBR] = self.type.decode(bytes, curr, byteBR) [self.auxdatalen.value, curr, byteBR] = self.auxdatalen.decode(bytes, curr, byteBR) [self.nsources.value, curr, byteBR] = self.nsources.decode(bytes, curr, byteBR) [self.group.value, curr, byteBR] = self.group.decode(bytes, curr, byteBR) srclen = self.nsources.value << 2 if srclen != 0: srclen = min(srclen, len(bytes)) endp = curr + srclen while curr < endp: src = pcs.Field("", 32) [src.value, curr, byteBR] = src.decode(bytes, curr, byteBR) self.sources.append(src) auxdatalen = self.auxdatalen.value << 2 if auxdatalen != 0: auxdatalen = min(auxdatalen, len(bytes)) self.auxdata.append(pcs.StringField("", auxdatalen*8, \ default=bytes[curr:curr+auxdatalen])) curr += auxdatalen delta = curr - start self.width = 8 * delta #print "consumed %d bytes" % delta return [bytes, curr, byteBR] def encode(self, bytearray, value, byte, byteBR): """Encode an IGMPv3 group record.""" # # Just encode what we're told, don't try to bounds check the payload, # but do print warnings if protocol invariants were violated. # #if self.nsources.value != (len(self.sources) >> 2): # print "WARNING: nsources field is %d, should be %d." % \ # (self.nsources.value, len(self.sources) >> 2) #if self.auxdatalen.value != (len(self.auxdata) >> 2): # print "WARNING: auxdatalen field is %d, should be %d." % \ # (self.auxdata.value, len(self.auxdata) >> 2) [byte, byteBR] = self.type.encode(bytearray, self.type.value, byte, byteBR) [byte, byteBR] = self.auxdatalen.encode(bytearray, self.auxdatalen.value, byte, byteBR) [byte, byteBR] = self.nsources.encode(bytearray, self.nsources.value, byte, byteBR) [byte, byteBR] = self.group.encode(bytearray, self.group.value, byte, byteBR) [byte, byteBR] = self.sources.encode(bytearray, None, byte, byteBR) [byte, byteBR] = self.auxdata.encode(bytearray, None, byte, byteBR) return [byte, byteBR] def reset(self): """Return a resonable value to use in resetting a field of this type.""" return "" # PCS codes field widths for bits. # Both length fields in an individual IGMPv3 group record code for # 32 bit words. Calculate if the field's overall width lies within # the bounds of a valid GroupRecordField. def bounds(self, value): """Check the bounds of this field.""" minwidth = self.type.width + self.auxdatalen.width + \ self.nsources.width + self.group.width maxwidth = minwidth + (((2 ** auxdatalen.width) << 2) * 8) + \ (((2 ** nsources.width) << 2) * 8) if self.width < minwidth or self.width > maxwidth: raise FieldBoundsError, "GroupRecordField must be between %d " \ "and %d bytes wide" % (minwidth, maxwidth) def __eq__(self, other): """Test two group records lists for equality.""" if other is None: return False if self.type.value == other.type.value and \ self.auxdatalen.value == other.auxdatalen.value and \ self.nsources.value == other.nsources.value and \ self.group.value == other.group.value: # TODO: Do a dictionary style comparison, sources shouldn't # need to appear in same order. #print "other fields compare ok, trying to match sources" for i in xrange(len(self.sources)): if self.sources[i].value != other.sources[i].value: #print "no match" return False #print "match" return True #print "no match" return False def __ne__(self, other): return not self.__eq__(other) def default_compare(lp, lf, rp, rf): """Default comparison method. Compare all fields except auxdata. Source list must match exactly -- we can't treat it as a dictionary, yet.""" return lf.__eq__(rf) default_compare = staticmethod(default_compare) class report(pcs.Packet): """IGMPv3 Report""" #IGMPv3 report messages are always multicast to link scope group #224.0.0.22 (INADDR_ALLRPTS_GROUP), with IGMP type 0x22 #(IGMP_v3_HOST_MEMBERSHIP_REPORT), making them easy to identify. #At least one group record SHOULD exist in the variable-length #section at the end of each datagram. _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize an IGMPv3 report header""" reserved00 = pcs.Field("reserved00", 16) nrecords = pcs.Field("nrecords", 16) records = pcs.OptionListField("records") pcs.Packet.__init__(self, [reserved00, nrecords, records], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # Decode additional bytes into group records, if provided. # Group records are variable length structures. # Some IGMPv3 implementations re-use the same buffers which # may contain junk, so don't try to parse the entire packet # as a set of group record fields. if bytes is not None: curr = self.sizeof() byteBR = 8 found = 0 expected = self._fieldnames['nrecords'].value while len(self.records) < expected and curr < len(bytes): rec = GroupRecordField("") oldcurr = curr [dummy, curr, byteBR] = rec.decode(bytes, curr, byteBR) self.records.append(rec) #print len(self.records), "records parsed" self.data = payload.payload(bytes[curr:len(bytes)]) else: self.data = None def calc_length(self): """Calculate and store the length field(s) for this packet. An IGMPv3 report itself has no auxiliary data; the report header counts only the number of records it contains.""" # For each record I contain, set nsources to the number of source # entries, and set auxdatalen to the size of the auxiliary data # in 32-bit words. auxdata is an OptionListField of StringFields. record_list = self._fieldnames['records']._options for rec in record_list: rec.nsources.value = len(rec.sources) auxdatalen = 0 for aux in rec.auxdata._options: auxdatalen += aux.width / 8 rec.auxdatalen.value = auxdatalen >> 2 self.nrecords = len(record_list) pcs-0.6/pcs/packets/ipv6.py0000664000175000017500000001003311255512624015437 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ipv6.py,v 1.6 2006/08/01 13:35:58 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class that implements an IPv6 packet. # import pcs import udp, tcp, icmpv4 import ipv6_map import os from socket import AF_INET6, inet_ntop import inspect import time # extension header next header field. IPV6_HOPOPTS = 0 IPV6_RTHDR = 43 IPV6_FRAG = 44 IPV6_ESP = 50 IPV6_AH = 51 IPV6_NONE = 59 IPV6_DSTOPTS = 60 class ipv6(pcs.Packet): """IPv6""" _layout = pcs.Layout() _map = ipv6_map.map def __init__(self, bytes = None, timestamp = None, **kv): """IPv6 Packet from RFC 2460""" version = pcs.Field("version", 4, default = 6) traffic = pcs.Field("traffic_class", 8) flow = pcs.Field("flow", 20) length = pcs.Field("length", 16) next_header = pcs.Field("next_header", 8, discriminator=True) hop = pcs.Field("hop", 8) src = pcs.StringField("src", 16 * 8) dst = pcs.StringField("dst", 16 * 8) pcs.Packet.__init__(self, [version, traffic, flow, length, next_header, hop, src, dst], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): ## 40 bytes is the standard size of an IPv6 header offset = 40 self.data = self.next(bytes[offset:len(bytes)], timestamp = timestamp) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0.""" retval = "" for field in self._layout: if (field.name == "src" or field.name == "dst"): value = inet_ntop(AF_INET6, field.value) retval += "%s %s\n" % (field.name, value) else: retval += "%s %d\n" % (field.name, field.value) return retval def getipv6(self, iface): """return one ipv6 address associated to iface""" v6 = "" # XXX: improve this using getifaddrs() wrapper. for line in os.popen("/sbin/ifconfig %s" % iface): if line.find('inet6') > -1: if line.split()[1][:4] == "fe80" or line.split()[1][:4] == "fec0": continue v6 = line.split()[1] break return v6 pcs-0.6/pcs/packets/dvmrp.py0000664000175000017500000000710111255512624015705 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: A class which describes DVMRP messages, as encapsulated # inside the payload of an IGMP type 0x13 message. # import inspect import pcs import struct import time from pcs.packets import payload from pcs.packets.igmpv2 import * from socket import AF_INET, inet_ntop, inet_ntoa # # DVMRP message types. # # The original DVMRP is specified in RFC 1075. The additional message # types used for mtrace/mrinfo are described in draft-ietf-idmr-dvmrp-v3. # DVMRP_NULL = 0 DVMRP_PROBE = 1 DVMRP_REPORT = 2 DVMRP_ASK_NEIGHBORS = 3 DVMRP_NEIGHBORS = 4 DVMRP_ASK_NEIGHBORS2 = 5 DVMRP_NEIGHBORS2 = 6 DVMRP_PRUNE = 7 DVMRP_GRAFT = 8 DVMRP_GRAFT_ACK = 9 DVMRP_INFO_REQUEST = 10 DVMRP_INFO_REPLY = 11 DVMRP_CAP_LEAF = 0x01 # This DVMRP peer is a leaf. DVMRP_CAP_PRUNE = 0x02 # This DVMRP peer understands pruning. DVMRP_CAP_GENID = 0x04 # This DVMRP peer sends Generation IDs. DVMRP_CAP_MTRACE = 0x08 # This DVMRP peer understands MTRACE. DVMRP_CAP_SNMP = 0x10 # This DVMRP peer supports the DVMRP MIB. # Default mask advertised by the Xerox PARC mrouted code. DVMRP_CAP_DEFAULT = (DVMRP_CAP_PRUNE | \ DVMRP_CAP_GENID | \ DVMRP_CAP_MTRACE ) class dvmrp(pcs.Packet): """DVMRP message, as defined in RFC 1075.""" layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize a header very similar to that of IGMPv1/v2""" reserved00 = pcs.Field("reserved00", 8) capabilities = pcs.Field("capabilities", 8) minor = pcs.Field("minor", 8) major = pcs.Field("major", 8) options = pcs.OptionListField("options") pcs.Packet.__init__(self, [reserved00, capabilities, minor, major, options], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # XXX optional bytes not processed yet. if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None pcs-0.6/pcs/packets/arp.py0000664000175000017500000001207711255512624015347 0ustar andreasandreas# Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: arp.py,v 1.2 2006/08/01 13:35:58 gnn Exp $ # # Author: George V. Neville-Neil # # Description: ARP packet class import pcs import struct from socket import AF_INET, inet_ntop, inet_ntoa import time, inspect ARPHRD_ETHER = 1 # ethernet hardware format ARPHRD_IEEE802 = 6 # token-ring hardware format ARPHRD_ARCNET = 7 # arcnet hardware format ARPHRD_FRELAY = 15 # frame relay hardware format ARPHRD_IEEE1394 = 24 # firewire hardware format ARPOP_REQUEST = 1 # request to resolve address ARPOP_REPLY = 2 # response to previous request ARPOP_REVREQUEST = 3 # request protocol address given hardware ARPOP_REVREPLY = 4 # response giving protocol address ARPOP_INVREQUEST = 8 # request to identify peer ARPOP_INVREPLY = 9 # response identifying peer class arp(pcs.Packet): """ARP""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize an ARP packet""" hrd = pcs.Field("hrd", 16, default = 1) pro = pcs.Field("pro", 16, default = 0x800) hln = pcs.Field("hln", 8, default = 6) pln = pcs.Field("pln", 8, default = 4) op = pcs.Field("op", 16) sha = pcs.StringField("sha", 48) spa = pcs.Field("spa", 32) tha = pcs.StringField("tha", 48) tpa = pcs.Field("tpa", 32) pcs.Packet.__init__(self, [hrd, pro, hln, pln, op, sha, spa, tha, tpa], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp self.data = None def __str__(self): """return a human readable version of an ARP packet""" retval = "ARP\n" retval += "hrd: " retval += "%d\n" % self.hrd retval += "pro: " retval += "%d\n" % self.pro retval += "hln: " retval += "%d\n" % self.hln retval += "pln: " retval += "%d\n" % self.pln retval += "op: " retval += "%d\n" % self.op retval += "sha: " if len(self.sha) >= 6: for byte in range(0,5): retval += "%s:" % hex(ord(self.sha[byte]))[2:4] retval += "%s\n" % hex(ord(self.sha[5]))[2:4] retval += "spa: " retval += "%s\n" % inet_ntop(AF_INET, struct.pack('!L', self.spa)) retval += "tha: " if len(self.tha) >= 6: for byte in range(0,5): retval += "%s:" % hex(ord(self.tha[byte]))[2:4] retval += "%s\n" % hex(ord(self.tha[5]))[2:4] retval += "tpa: " retval += "%s\n" % inet_ntop(AF_INET, struct.pack('!L', self.tpa)) return retval # # Functions defined for the module. # def ether_atob(pretty): """Take a pretty version of an ethernet address and convert it to a string of bytes. The input string MUST be of the form xx:yy:zz:aa:bb:cc and leading zero's must be supplied. Nor error checking is performed. """ addr = "" for i in 0, 3, 6, 9, 12, 15: addr += "%c" % int(pretty[i:i+2], 16) return addr def ether_btoa(bytes): """Take a set of bytes and convert them to a pretty version of and Ethernet address. The input buffer MUST be at least 6 bytes long and bytes after the sixth are ignored. No error checking is performed. """ pretty = "" for i in (range(5)): pretty += hex(bytes[i])[2:4] # Strip the 0x from the string pretty += ':' pretty += hex(bytes[5])[2:4] # Strip the 0x from the string return pretty pcs-0.6/pcs/packets/igmp.py0000664000175000017500000000703611255512624015520 0ustar andreasandreasimport pcs from socket import AF_INET, inet_ntop import struct import inspect import time import pcs.packets.ipv4 import pcs.packets.igmpv2 as igmpv2 import pcs.packets.igmpv3 as igmpv3 #import pcs.packets.dvmrp #import pcs.packets.mtrace IGMP_HOST_MEMBERSHIP_QUERY = 0x11 IGMP_v1_HOST_MEMBERSHIP_REPORT = 0x12 IGMP_DVMRP = 0x13 IGMP_v2_HOST_MEMBERSHIP_REPORT = 0x16 IGMP_HOST_LEAVE_MESSAGE = 0x17 IGMP_v3_HOST_MEMBERSHIP_REPORT = 0x22 IGMP_MTRACE_REPLY = 0x1e IGMP_MTRACE_QUERY = 0x1f igmp_map = { IGMP_HOST_MEMBERSHIP_QUERY: igmpv2.igmpv2, IGMP_v1_HOST_MEMBERSHIP_REPORT: igmpv2.igmpv2, #IGMP_DVMRP: dvmrp.dvmrp, IGMP_v2_HOST_MEMBERSHIP_REPORT: igmpv2.igmpv2, IGMP_HOST_LEAVE_MESSAGE: igmpv2.igmpv2, #IGMP_MTRACE_REPLY: mtrace.reply, #IGMP_MTRACE_QUERY: mtrace.query, IGMP_v3_HOST_MEMBERSHIP_REPORT: igmpv3.report } descr = { IGMP_HOST_MEMBERSHIP_QUERY: "IGMPv2 Query", IGMP_v1_HOST_MEMBERSHIP_REPORT: "IGMPv1 Report", IGMP_DVMRP: "DVMRP", IGMP_v2_HOST_MEMBERSHIP_REPORT: "IGMPv2 Report", IGMP_HOST_LEAVE_MESSAGE: "IGMPv2 Leave", IGMP_MTRACE_REPLY: "MTRACE Reply", IGMP_MTRACE_QUERY: "MTRACE Query", IGMP_v3_HOST_MEMBERSHIP_REPORT: "IGMPv3 Report" } class igmp(pcs.Packet): """IGMP""" _layout = pcs.Layout() _map = igmp_map _descr = descr def __init__(self, bytes = None, timestamp = None, **kv): """ Define the common IGMP encapsulation; see RFC 2236. """ type = pcs.Field("type", 8, discriminator=True) code = pcs.Field("code", 8) checksum = pcs.Field("checksum", 16) pcs.Packet.__init__(self, [type, code, checksum], bytes = bytes, **kv) # Description MUST be set after the PCS layer init self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() if self.type == IGMP_HOST_MEMBERSHIP_QUERY and \ len(bytes) >= igmpv3.IGMP_V3_QUERY_MINLEN: self.data = igmpv3.query(bytes[offset:len(bytes)], timestamp = timestamp) else: # XXX Workaround Packet.next() -- it only returns something # if it can discriminate. self.data = self.next(bytes[offset:len(bytes)], timestamp = timestamp) if self.data is None: self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None def rdiscriminate(self, packet, discfieldname = None, map = igmp_map): """Reverse-map an encapsulated packet back to a discriminator field value. Like next() only the first match is used.""" #print "reverse discriminating %s" % type(packet) return pcs.Packet.rdiscriminate(self, packet, "type", map) def calc_checksum(self): """Calculate and store the checksum for this IGMP header. IGMP checksums are computed over payloads too.""" from pcs.packets.ipv4 import ipv4 self.checksum = 0 tmpbytes = self.bytes if not self._head is None: tmpbytes += self._head.collate_following(self) self.checksum = ipv4.ipv4_cksum(tmpbytes) def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" retval = self._descr[self.type] + "\n" for field in self._layout: retval += "%s %s\n" % (field.name, field.value) return retval pcs-0.6/pcs/packets/ieee8023ad.py0000664000175000017500000001373011255512624016313 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe IEEE 802.3ad Slow Protocols. # import inspect import struct import time import pcs import pcs.packets.payload # TODO: Ethernet OAM support. # TODO: Hook up to Ethernet decoder. ETHER_GROUP_SLOW = "\x01\x80\xc2\x00\x00\x02" SLOWPROTOCOLS_SUBTYPE_LACP = 1 SLOWPROTOCOLS_SUBTYPE_MARKER = 2 SLOWPROTOCOLS_SUBTYPE_OAM = 3 # LACP TLVs. # I *think* 0 marks the end of the TLVs. LACP_TYPE_ACTORINFO = 1 LACP_TYPE_PARTNERINFO = 2 LACP_TYPE_COLLECTORINFO = 3 MARKER_TYPE_INFO = 0x01 MARKER_TYPE_RESPONSE = 0x02 # OAM is: # [version byte from slowhdr is actually upper 8 bits of flags, ignored.] # flagslo 1 # code 1 # 0..N OAM TLVs # TODO: The OAM flags need double checking against spec for IEEE bit order. # OAM Flags OAM_F_REMOTE_STABLE = 0x01 OAM_F_REMOTE_EVALUATING = 0x02 OAM_F_LOCAL_STABLE = 0x04 OAM_F_LOCAL_EVALUATING = 0x08 OAM_F_CRITICAL_EVENT = 0x10 OAM_F_DYING_GASP = 0x20 OAM_F_FAULT = 0x40 # OAM Type OAM_TYPE_INFO = 0 OAM_TYPE_NOTIFY = 1 OAM_TYPE_REQUEST = 2 OAM_TYPE_RESPONSE = 3 OAM_TYPE_LOOPBACK = 4 # OAMPDU Loopback commands OAM_LOOPBACK_ENABLE = 0x01 OAM_LOOPBACK_DISABLE = 0x02 # OAMPDU INFO frame TLV types OAM_INFO_TLV_LOCAL = 0x01 OAM_INFO_TLV_REMOTE = 0x02 # OAMPDU State field OAM_STATE_F_MUX_ACTION = 0x04 OAM_STATE_F_PARSE_ACTION = 0x03 # mask 0:1 # OAMPDU Config field OAM_CFG_F_HAS_RETRIEVAL = 0x10 OAM_CFG_F_HAS_EVENTS = 0x08 OAM_CFG_F_HAS_LOOPBACK = 0x04 OAM_CFG_F_HAS_SIMPLEX = 0x02 OAM_CFG_F_IS_ACTIVE = 0x01 # TODO: OAM Link Event TLV Types Table 57-12 class lacp(pcs.Packet): """IEEE 802.3ad Slow Protocols -- LACP""" # composed of: actor, partner, collector, term TLVs. _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): # composed entirely of TLVs. tlvs = pcs.OptionListField("tlvs") pcs.Packet.__init__(self, [ tlvs ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = 0 remaining = len(bytes) # XXX Need to decode the LACP TLVs here, however, # TLV needs to be able to contain OptionLists to proceed... self.data = payload(bytes[self.sizeof():len(bytes)], timestamp = timestamp) else: self.data = None class marker(pcs.Packet): """IEEE 802.3ad Slow Protocols -- Marker""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): # XXX: TLV fields can't contain multiple values yet, so we # kludge by making the first TLV fields exposed here. it = pcs.Field("info_type", 8) il = pcs.Field("info_len", 8) port = pcs.Field("port", 16) system = pcs.StringField("system", 6*8) xid = pcs.Field("xid", 32) pad = pcs.Field("pad", 16) tt = pcs.Field("term_type", 8) tl = pcs.Field("term_len", 8) resv = pcs.StringField("resv", 90 * 8) pcs.Packet.__init__(self, [ it, il, port, system, xid, pad, \ tt, tl, resv ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: self.data = payload(bytes[self.sizeof():len(bytes)], timestamp = timestamp) else: self.data = None map = { SLOWPROTOCOLS_SUBTYPE_LACP: lacp, SLOWPROTOCOLS_SUBTYPE_MARKER: marker #SLOWPROTOCOLS_SUBTYPE_OAM: oam } class slowhdr(pcs.Packet): """IEEE 802.3ad Slow Protocols -- common header""" _layout = pcs.Layout() _map = map _descr = None def __init__(self, bytes = None, timestamp = None, **kv): subtype = pcs.Field("subtype", 8) version = pcs.Field("version", 8) pcs.Packet.__init__(self, [subtype, version], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: self.data = frame(bytes[self.sizeof():len(bytes)], timestamp = timestamp) else: self.data = None pcs-0.6/pcs/packets/tcp.py0000664000175000017500000003446111255512624015354 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: tcp.py,v 1.5 2006/07/06 09:31:57 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class that describes a TCP packet. import sys import pcs import tcp_map from pcs import UnpackError from pcs.packets import payload import inspect import time import struct class tcp(pcs.Packet): """TCP""" _layout = pcs.Layout() _map = None def __init__(self, bytes = None, timestamp = None, **kv): """initialize a TCP packet""" sport = pcs.Field("sport", 16) dport = pcs.Field("dport", 16) seq = pcs.Field("sequence", 32) acknum = pcs.Field("ack_number", 32) off = pcs.Field("offset", 4) reserved = pcs.Field("reserved", 6) urg = pcs.Field("urgent", 1) ack = pcs.Field("ack", 1) psh = pcs.Field("push", 1) rst = pcs.Field("reset", 1) syn = pcs.Field("syn", 1) fin = pcs.Field("fin", 1) window = pcs.Field("window", 16) checksum = pcs.Field("checksum", 16) urgp = pcs.Field("urg_pointer",16) options = pcs.OptionListField("options") pcs.Packet.__init__(self, [sport, dport, seq, acknum, off, reserved, urg, ack, psh, rst, syn, fin, window, checksum, urgp, options], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # Decode TCP options. if bytes is not None: data_offset = self.offset * 4 # in bytes options_len = data_offset - self.sizeof() # Sanity check that the buffer we are given is large enough # to contain the TCP header, or else TCP option decode will # fail. This usually indicates a problem below, i.e. we # tried to copy a segment and didn't create fields to back # the options, causing the data to be lost. # If options are present then they must fit into the 40 byte # option area. We will perform this check during encoding later. if data_offset > len(bytes): raise UnpackError, \ "TCP segment is larger than input (%d > %d)" % \ (data_offset, len(bytes)) if (options_len > 0): curr = self.sizeof() while (curr < data_offset): option = struct.unpack('!B', bytes[curr])[0] #print "(curr = %d, data_offset = %d, option = %d)" % \ # (curr, data_offset, option) # Special-case options which do not have a length field. if option == 0: # end options.append(pcs.Field("end", 8, default = 0)) curr += 1 #break # immediately stop processing. continue # immediately stop processing. elif option == 1: # nop options.append(pcs.Field("nop", 8, default = 1)) curr += 1 continue optlen = struct.unpack('!B', bytes[curr+1])[0] if (optlen < 1 or optlen > (data_offset - curr)): raise UnpackError, \ "Bad length %d for TCP option %d" % \ (optlen, option) # XXX we could break this out into a map. # option lengths include the length of the code byte, # length byte, and the option data. the fly in the # buttermilk of course is that they do not 1:1 map # onto TLVs, see above, but they need to if we plan # to use the existing object model. #print "\t(optlen %d)" % (optlen) if option == 2: # mss # XXX This is being thrown, not sure why. #if optlen != 4: # print options # raise UnpackError, \ # "Bad length %d for TCP option %d, should be %d" % \ # (optlen, option, 4) value = struct.unpack("!H", bytes[curr+2:curr+4])[0] # XXX does tlv encode a length in bits or bytes?? # 'cuz a second pass spits out 'it's optlen 16'" options.append(pcs.TypeLengthValueField("mss", \ pcs.Field("t", 8, default = option), \ pcs.Field("l", 8, default = optlen), \ pcs.Field("v", 16, default = value))) curr += optlen elif option == 3: # wscale if optlen != 3: raise UnpackError, \ "Bad length %d for TCP option %d, should be %d" % \ (optlen, option, 3) value = struct.unpack("B", bytes[curr+2:curr+3])[0] options.append(pcs.TypeLengthValueField("wscale", \ pcs.Field("t", 8, default = option), \ pcs.Field("l", 8, default = optlen), \ pcs.Field("v", 8, default = value))) curr += optlen elif option == 4: # sackok if optlen != 2: raise UnpackError, \ "Bad length %d for TCP option %d, should be %d" % \ (optlen, option, 2) options.append(pcs.TypeLengthValueField("sackok", \ pcs.Field("t", 8, default = option), \ pcs.Field("l", 8, default = optlen), \ pcs.Field("v", 0, default = value))) curr += optlen elif option == 5: # sack # this is a variable length option, the permitted # range is 2 + 1..4*sizeof(sackblock) subject # to any other options. sacklen = optlen - 2 value = struct.unpack("%dB" % sacklen, bytes[curr+2:curr+sacklen])[0] options.append(pcs.TypeLengthValueField("sack", \ pcs.Field("t", 8, default = option), \ pcs.Field("l", 8, default = optlen), \ pcs.Field("v", sacklen * 8, default = value))) curr += optlen elif option == 8: # tstamp if optlen != 10: raise UnpackError, \ "Bad length %d for TCP option %d, should be %d" % \ (optlen, option, 10) value = struct.unpack("!2I", bytes[curr+2:curr+10])[0] options.append(pcs.TypeLengthValueField("tstamp", \ pcs.Field("t", 8, default = option), \ pcs.Field("l", 8, default = optlen), \ pcs.Field("v", 64, default = value))) curr += optlen #elif option == 19: # md5 # if optlen != 18: # raise UnpackError, \ # "Bad length %d for TCP option %d, should be %d" % \ # (optlen, option, 18) # value = struct.unpack("16B", bytes[curr+2:curr+16])[0] # options.append(pcs.TypeLengthValueField("md5", \ # pcs.Field("t", 8, default = option), \ # pcs.Field("l", 8, default = optlen), \ # pcs.Field("v", 64, default = value))) # curr += optlen else: #print "warning: unknown option %d" % option optdatalen = optlen - 2 value = struct.unpack("!B", bytes[curr+2:curr+optdatalen])[0] options.append(pcs.TypeLengthValueField("unknown", \ pcs.Field("t", 8, default = option), \ pcs.Field("l", 8, default = optlen), \ pcs.Field("v", optdatalen * 8, default = value))) curr += optlen if (bytes is not None and (self.offset * 4 < len(bytes))): self.data = self.next(bytes[(self.offset * 4):len(bytes)], timestamp = timestamp) else: self.data = None # XXX TCP MUST have it's own next() function so that it can discrimnate # on either sport or dport. def next(self, bytes, timestamp): """Decode higher layer packets contained in TCP.""" if (self.dport in tcp_map.map): return tcp_map.map[self.dport](bytes, timestamp = timestamp) if (self.sport in tcp_map.map): return tcp_map.map[self.sport](bytes, timestamp = timestamp) return None def __str__(self): """Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0.""" retval = "TCP\n" for field in self._layout: retval += "%s %s\n" % (field.name, field.value) return retval def pretty(self, attr): """Pretty prting a field""" pass def cksum(self, ip, data = ""): """Calculate the TCP segment checksum outside of a chain.""" from pcs.packets.ipv4 import ipv4 from pcs.packets.ipv4 import pseudoipv4 from socket import IPPROTO_TCP tmpip = pseudoipv4() tmpip.src = ip.src tmpip.dst = ip.dst tmpip.protocol = IPPROTO_TCP tmpip.length = len(self.getbytes()) + len(data) pkt = tmpip.getbytes() + self.getbytes() + data return ipv4.ipv4_cksum(pkt) # XXX The following code is common to both the TCP and UDP modules, # and could be moved into another module or class. def calc_checksum(self): """Calculate and store the checksum for this TCP segment. The packet must be part of a chain. We attempt to infer whether IPv4 or IPv6 encapsulation is in use for the payload. The closest header wins the match. The network layer header must immediately precede the TCP segment (for now).""" from pcs.packets.ipv4 import ipv4 ip = None ip6 = None if self._head is not None: (ip, iip) = self._head.find_preceding(self, pcs.packets.ipv4.ipv4) (ip6, iip6) = self._head.find_preceding(self, pcs.packets.ipv6.ipv6) # Either this TCP header is not in a chain, or no IPv4/IPv6 # outer header was found. if ip is None and ip6 is None: self.checksum = 0 self.checksum = ipv4.ipv4_cksum(self.getbytes()) return # If we found both IPv4 and IPv6 headers then we must break the tie. # The closest outer header wins and is used for checksum calculation. if ip is not None and ip6 is not None: assert iip != iip6, "ipv4 and ipv6 cannot be at same index" if iip6 > iip: ip = None # ip6 is nearest outer header, ignore ip else: ip6 = None # ip is nearest outer header, ignore ip6 if ip is not None: self.calc_checksum_v4(ip) else: self.calc_checksum_v6(ip6) def calc_checksum_v4(self, ip): """Calculate and store the checksum for the TCP segment when encapsulated as an IPv4 payload with the given header.""" from pcs.packets.ipv4 import ipv4 from pcs.packets.ipv4 import pseudoipv4 from socket import IPPROTO_TCP self.checksum = 0 payload = self._head.collate_following(self) pip = pseudoipv4() pip.src = ip.src pip.dst = ip.dst pip.protocol = IPPROTO_TCP pip.length = len(self.getbytes()) + len(payload) tmpbytes = pip.getbytes() + self.getbytes() + payload self.checksum = ipv4.ipv4_cksum(tmpbytes) def calc_checksum_v6(self, ip6): """Calculate and store the checksum for the TCP segment when encapsulated as an IPv6 payload with the given header.""" from pcs.packets.ipv4 import ipv4 from pcs.packets.pseudoipv6 import pseudoipv6 self.checksum = 0 payload = self._head.collate_following(self) pip6 = pseudoipv6() pip6.src = ip6.src pip6.dst = ip6.dst pip6.next_header = ip6.next_header pip6.length = len(self.getbytes()) + len(payload) tmpbytes = pip6.getbytes() + self.getbytes() + payload self.checksum = ipv4.ipv4_cksum(tmpbytes) def calc_length(self): """Calculate and store the length field(s) for this packet. For TCP, we need only calculate the length of the header and any appended options; the length of the TCP payload is calculated from the length field in the outer IP/IP6 header.""" tmpoff = len(self.getbytes()) self.off = (tmpoff >> 2) pcs-0.6/pcs/packets/ipv6_map.py0000664000175000017500000000411011255512624016273 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: This is a module which maps IPv4 protocol numbers to # class names for use by the IPv4 class. # The map is a dictionary who's key is the protocol type and who's # value is the class constructor for that type. from socket import IPPROTO_UDP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_ESP, IPPROTO_ICMP IPPROTO_SCTP = 132 import udp, tcp, ipsec, icmpv6 # sctp map = {IPPROTO_UDP: udp.udp, IPPROTO_TCP: tcp.tcp, IPPROTO_AH: ipsec.ah, IPPROTO_ESP: ipsec.esp, IPPROTO_ICMP: icmpv6.icmpv6} pcs-0.6/pcs/packets/dns.py0000664000175000017500000001503011255512624015341 0ustar andreasandreas# Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: dns.py,v 1.4 2006/09/01 07:45:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: DNS Packet Class import pcs import inspect import time class dnsheader(pcs.Packet): """DNS Header""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, tcp = None, **kv): """Define the fields of a DNS (RFC 1035) header""" id = pcs.Field("id", 16) query = pcs.Field("query", 1) opcode = pcs.Field("opcode", 4) aa = pcs.Field("aa", 1) tc = pcs.Field("tc", 1) rd = pcs.Field("rd", 1) ra = pcs.Field("ra", 1) z = pcs.Field("z", 3, default = 0) rcode = pcs.Field("rcode", 4) qdcount = pcs.Field("qdcount", 16) ancount = pcs.Field("ancount", 16) nscount = pcs.Field("nscount", 16) arcount = pcs.Field("arcount", 16) # DNS Headers on TCP require a length but when encoded in UDP do not. # TODO: Add chain support to figure out dynamically if this # dnsheader is being encapsulated in TCP or UDP using find_preceding(), # and modify the layout accordingly. self.is_tcp = False if (tcp is not None): self.is_tcp = True length = pcs.Field("length", 16) pcs.Packet.__init__(self, [length, id, query, opcode, aa, tc, rd, ra, z, rcode, qdcount, ancount, nscount, arcount], bytes = bytes, **kv) else: pcs.Packet.__init__(self, [id, query, opcode, aa, tc, rd, ra, z, rcode, qdcount, ancount, nscount, arcount], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # Unconditionally the last packet in a chain # XXX This is obviously incorrect. We need to decode payload # if we have one -- we may contain labels, etc. self.data = None def calc_length(self): """Calculate and store the length field(s) for this packet. DNS headers are prepended with a length field iff they are encapsulated in TCP. The length is non-inclusive, it does not include the length of the length field, however it does include the length of any following payload.""" if self.is_tcp is True: self.length = len(self.getbytes()) - 2 if self._head is not None: self.length += len(self._head.collate_following(self)) class dnslabel(pcs.Packet): """DNS Label""" _layout = pcs.Layout() def __init__(self, bytes = None): """initialize a DNS label, which is a component of a domain name""" name = pcs.LengthValueField("name", 8) pcs.Packet.__init__(self, [name], bytes = bytes) self.description = inspect.getdoc(self) class dnsquery(pcs.Packet): """DNS Query""" _layout = pcs.Layout() def __init__(self, bytes = None): """initialize a DNS query packet, which is a query for information""" type = pcs.Field("type", 16) qclass = pcs.Field("query_class", 16) pcs.Packet.__init__(self, [type, qclass], bytes = bytes) self.description = inspect.getdoc(self) # # XXX 'name' should actually be a label-or-pointer-sequence. # Of course there is no way of knowing unless we a) type DNS # entities to use a different string field, and b) perform # the compression when we come to encode. # 'rdata' can contain arbitrary data depending on qclass, # however, the valid total length of a UDP dns packet is 512 bytes. # # Below for now both field contents are limited to 32 bytes ( 2 ** 4 * 8), # the length fields remain the same as per RFC 1035. # class dnsrr(pcs.Packet): """DNS Resource Record""" _layout = pcs.Layout() def __init__(self, bytes = None): """initialize a DNS resource record, which encodes data returned from a query""" #name = pcs.LengthValueField("name", pcs.Field("", 8), # pcs.StringField("", (2 ** 8) * 8)) name = pcs.LengthValueField("name", pcs.Field("", 8), pcs.StringField("", 2 ** 4 * 8)) # XXX type = pcs.Field("type", 16) qclass = pcs.Field("query_class", 16) ttl = pcs.Field("ttl", 32) #rdata = pcs.LengthValueField("rdata", pcs.Field("", 16), # pcs.StringField("", (2 ** 16) * 8)) rdata = pcs.LengthValueField("rdata", pcs.Field("", 16), pcs.StringField("", 2 ** 4 * 8)) # XXX pcs.Packet.__init__(self, [name, type, qclass, ttl, rdata], bytes = bytes) self.description = inspect.getdoc(self) pcs-0.6/pcs/packets/rtnetlink.py0000664000175000017500000004544411255512624016603 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe RFC 3549 Netlink socket messages # for the NETLINK_ROUTE group. # import inspect import struct import time import pcs import payload # TODO: Add a LengthTypeValue field to model the general TLV format. # TODO: Test all this. # TODO: Cacheinfo, VLAN TLVs. # TODO: IPv6 neighbor discovery. # TODO: Queueing/traffic control/filtering. # # rtnetlink group IDs (as bit numbers from 1-32). # RTNLGRP_NONE = 0 RTNLGRP_LINK = 1 RTNLGRP_NOTIFY = 2 RTNLGRP_NEIGH = 3 RTNLGRP_TC = 4 RTNLGRP_IPV4_IFADDR = 5 RTNLGRP_IPV4_MROUTE = 6 RTNLGRP_IPV4_ROUTE = 7 RTNLGRP_IPV4_RULE = 8 RTNLGRP_IPV6_IFADDR = 9 RTNLGRP_IPV6_MROUTE = 10 RTNLGRP_IPV6_ROUTE = 11 RTNLGRP_IPV6_IFINFO = 12 RTNLGRP_IPV6_PREFIX = 18 RTNLGRP_IPV6_RULE = 19 RTNLGRP_ND_USEROPT = 20 # # Userland backwards compatibility for rtnetlink group IDs. # RTMGRP_LINK = (1 << (RTNLGRP_LINK - 1)) RTMGRP_NOTIFY = (1 << (RTNLGRP_NOTIFY - 1)) RTMGRP_NEIGH = (1 << (RTNLGRP_NEIGH - 1)) RTMGRP_TC = (1 << (RTNLGRP_TC - 1)) RTMGRP_IPV4_IFADDR = (1 << (RTNLGRP_IPV4_IFADDR - 1)) RTMGRP_IPV4_MROUTE = (1 << (RTNLGRP_IPV4_MROUTE - 1)) RTMGRP_IPV4_ROUTE = (1 << (RTNLGRP_IPV4_ROUTE - 1)) RTMGRP_IPV4_RULE = (1 << (RTNLGRP_IPV4_RULE - 1)) RTMGRP_IPV6_IFADDR = (1 << (RTNLGRP_IPV6_IFADDR - 1)) RTMGRP_IPV6_MROUTE = (1 << (RTNLGRP_IPV6_MROUTE - 1)) RTMGRP_IPV6_ROUTE = (1 << (RTNLGRP_IPV6_ROUTE - 1)) RTMGRP_IPV6_IFINFO = (1 << (RTNLGRP_IPV6_IFINFO - 1)) RTMGRP_IPV6_PREFIX = (1 << (RTNLGRP_IPV6_PREFIX - 1)) # # rtnetlink message types # # struct ifinfomsg RTM_NEWLINK = 16 RTM_DELLINK = 17 RTM_GETLINK = 18 RTM_SETLINK = 19 # struct ifaddrmsg RTM_NEWADDR = 20 RTM_DELADDR = 21 RTM_GETADDR = 22 # struct rtmsg RTM_NEWROUTE = 24 RTM_DELROUTE = 23 RTM_GETROUTE = 24 # # Embedded RTnetlink TLVs are normally encoded (len, type, payload) # where len and type are uint16_t. # # # rtmsg.type values # RTN_UNSPEC = 0 RTN_UNICAST = 1 RTN_LOCAL = 2 RTN_BROADCAST = 3 RTN_ANYCAST = 4 RTN_MULTICAST = 5 RTN_BLACKHOLE = 6 RTN_UNREACHABLE = 7 RTN_PROHIBIT = 8 RTN_THROW = 9 RTN_NAT = 10 RTN_XRESOLVE = 11 # # rtmsg.protocol origin IDs # RTPROT_UNSPEC = 0 RTPROT_REDIRECT = 1 RTPROT_KERNEL = 2 RTPROT_BOOT = 3 RTPROT_STATIC = 4 RTPROT_GATED = 8 RTPROT_RA = 9 RTPROT_MRT = 10 RTPROT_ZEBRA = 11 RTPROT_BIRD = 12 RTPROT_DNROUTED = 13 RTPROT_XORP = 14 RTPROT_NTK = 15 # # rtmsg.scope IDs. # RT_SCOPE_UNIVERSE = 0 RT_SCOPE_SITE = 200 RT_SCOPE_LINK = 253 RT_SCOPE_HOST = 254 RT_SCOPE_NOWHERE = 255 # # rtmsg.flags # RTM_F_NOTIFY = 0x100 RTM_F_CLONED = 0x200 RTM_F_EQUALIZE = 0x400 RTM_F_PREFIX = 0x800 # # rtmsg.table IDs. # RT_TABLE_UNSPEC = 0 RT_TABLE_DEFAULT = 253 RT_TABLE_MAIN = 254 RT_TABLE_LOCAL = 255 RT_TABLE_MAX = 0xFFFFFFFF # # rtmsg TLVs [0..N following rtmsg] # RTA_UNSPEC = 0 RTA_DST = 1 RTA_SRC = 2 RTA_IIF = 3 RTA_OIF = 4 RTA_GATEWAY = 5 RTA_PRIORITY = 6 RTA_PREFSRC = 7 RTA_METRICS = 8 RTA_MULTIPATH = 9 # Contains 0..N NexthopFields RTA_PROTOINFO = 10 RTA_FLOW = 11 # TODO RTA_CACHEINFO = 12 # TODO RTA_SESSION = 13 # TODO RTA_TABLE = 15 # # Flags for a NexthopField. # RTNH_F_DEAD = 1 RTNH_F_PERVASIVE = 2 RTNH_F_ONLINK = 4 # # RTA_METRICS TLV [0..13 of metrics for this prefix] # RTAX_UNSPEC = 0 RTAX_LOCK = 1 RTAX_MTU = 2 RTAX_WINDOW = 3 RTAX_RTT = 4 RTAX_RTTVAR = 5 RTAX_SSTHRESH = 6 RTAX_CWND = 7 RTAX_ADVMSS = 8 RTAX_REORDERING = 9 RTAX_HOPLIMIT = 10 RTAX_INITCWND = 11 RTAX_FEATURES = 12 RTAX_RTO_MIN = 13 RTAX_FEATURE_ECN = 0x00000001 RTAX_FEATURE_SACK = 0x00000002 RTAX_FEATURE_TIMESTAMP = 0x00000004 RTAX_FEATURE_ALLFRAG = 0x00000008 # # IFA TLV IDs. # IFA_UNSPEC = 0 IFA_ADDRESS = 1 IFA_LOCAL = 2 IFA_LABEL = 3 IFA_BROADCAST = 4 IFA_ANYCAST = 5 IFA_CACHEINFO = 6 IFA_MULTICAST = 7 # # ifa_flags # IFA_F_SECONDARY = 0x01 IFA_F_TEMPORARY = IFA_F_SECONDARY IFA_F_NODAD = 0x02 IFA_F_OPTIMISTIC = 0x04 IFA_F_HOMEADDRESS = 0x10 IFA_F_DEPRECATED = 0x20 IFA_F_TENTATIVE = 0x40 IFA_F_PERMANENT = 0x80 # # Interface flags in the RTnetlink namespace. # [Scope IDs are as for route messages.] # IFF_UP = 0x1 IFF_BROADCAST = 0x2 IFF_DEBUG = 0x4 IFF_LOOPBACK = 0x8 IFF_POINTOPOINT = 0x10 IFF_NOTRAILERS = 0x20 IFF_RUNNING = 0x40 IFF_NOARP = 0x80 IFF_PROMISC = 0x100 IFF_ALLMULTI = 0x200 IFF_MASTER = 0x400 IFF_SLAVE = 0x800 IFF_MULTICAST = 0x1000 IFF_PORTSEL = 0x2000 IFF_AUTOMEDIA = 0x4000 IFF_DYNAMIC = 0x8000 IFF_LOWER_UP = 0x10000 IFF_DORMANT = 0x20000 IFF_ECHO = 0x40000 # # Interface info TLV IDs. # IFLA_UNSPEC = 0 IFLA_ADDRESS = 1 IFLA_BROADCAST = 2 IFLA_IFNAME = 3 IFLA_MTU = 4 IFLA_LINK = 5 IFLA_QDISC = 6 IFLA_STATS = 7 IFLA_COST = 8 IFLA_PRIORITY = 9 IFLA_MASTER = 10 IFLA_WIRELESS = 11 IFLA_PROTINFO = 12 IFLA_TXQLEN = 13 IFLA_MAP = 14 # Bus specific, we can do without. IFLA_WEIGHT = 15 IFLA_OPERSTATE = 16 IFLA_LINKMODE = 17 IFLA_LINKINFO = 18 IFLA_NET_NS_PID = 19 # # PROTINFO sub TLV IDs. # IFLA_INET6_UNSPEC = 0 IFLA_INET6_FLAGS = 1 IFLA_INET6_CONF = 2 IFLA_INET6_STATS = 3 IFLA_INET6_MCAST = 4 IFLA_INET6_CACHEINFO = 5 IFLA_INET6_ICMP6STATS = 6 # # PREFIX TLV IDs. # PREFIX_UNSPEC = 0 # Unused. PREFIX_ADDRESS = 1 # The address prefix itself. PREFIX_CACHEINFO = 2 # (uint32_t,uint32_t) preferred, valid times. # # IPv6 prefix message flags. # IF_PREFIX_ONLINK = 0x01 IF_PREFIX_AUTOCONF = 0x02 class NexthopField(pcs.CompoundField): """An RTnetlink nexthop field contains information about each candidate next-hop known to the forwarding plane for a given prefix.""" _flag_bits = "\x01DEAD\x02PERVASIVE\x03ONLINK" def __init__(self, name, **kv): self.packet = None self.name = name self.len = pcs.Field("len", 16) self.flags = pcs.Field("flags", 8) self.hops = pcs.Field("hops", 8) self.ifindex = pcs.Field("ifindex", 32) self.tlvs = pcs.OptionListField("tlvs") # XXX I actually have variable width when I am being encoded, # OptionList deals with this. self.width = self.len.width + self.flags.width + \ self.hops.width + self.ifindex.width + \ self.tlvs.width # If keyword initializers are present, deal with the syntactic sugar. # TODO: Figure out how to initialize the TLVs inside our TLV... if kv is not None: for kw in kv.iteritems(): if kw[0] in self.__dict__: if kw[0] == 'tlvs': if not isinstance(kw[1], list): if __debug__: print "argument is not a list" continue #for src in kw[1]: # if not isinstance(src, int): # if __debug__: # print "source is not an IPv4 address" # continue # self.sources.append(pcs.Field("", 32, default=src)) else: self.__dict__[kw[0]].value = kw[1] def __repr__(self): return "" \ % (self.len, self.flags, self.hops, \ self.ifindex, self.tlvs) def __str__(self): """Walk the entire field and pretty print the values of the fields.""" retval = " Nexthop\n" retval += "Len %d\n" % self.len.value retval += "Flags %s\n" % bsprintf(self.flags.value, self._flag_bits) retval += "Hops %d\n" % self.hops.value retval += "Ifindex %s\n" % self.ifindex.value retval += "TLVs " i = False for s in self.tlvs._options: if i is False: retval += ", " ss = inet_ntop(AF_INET, struct.pack('!L', s.value)) retval += ss i = True return retval def __setattr__(self, name, value): object.__setattr__(self, name, value) if self.packet is not None: self.packet.__needencode = True def decode(self, bytes, curr, byteBR): start = curr [self.len.value, curr, byteBR] = self.len.decode(bytes, curr, byteBR) [self.flags.value, curr, byteBR] = self.flags.decode(bytes, curr, byteBR) [self.hops.value, curr, byteBR] = self.hops.decode(bytes, curr, byteBR) [self.ifindex.value, curr, byteBR] = self.ifindex.decode(bytes, curr, byteBR) # TODO Parse TLVs. #endp = curr + (self.nsources.value * 4) #remaining = len(bytes) - curr #endp = min(endp, remaining) #while curr < endp: # src = pcs.Field("", 32) # [src.value, curr, byteBR] = src.decode(bytes, curr, byteBR) # self.sources.append(src) #curr += auxdatalen #delta = curr - start #self.width = 8 * delta return [bytes, curr, byteBR] def encode(self, bytearray, value, byte, byteBR): """Encode a NexthopField.""" [byte, byteBR] = self.len.encode(bytearray, self.len.value, byte, byteBR) [byte, byteBR] = self.flags.encode(bytearray, self.flags.value, byte, byteBR) [byte, byteBR] = self.hops.encode(bytearray, self.hops.value, byte, byteBR) [byte, byteBR] = self.ifindex.encode(bytearray, self.ifindex.value, byte, byteBR) # XXX TODO encode the TLVs. return [byte, byteBR] def bounds(self, value): """Check the bounds of this field.""" # XXX assume maxwidth is inclusive minwidth = self.len.width + self.flags.width + \ self.hops.width + self.ifindex.width maxwidth = (2 ** self.len.width) * 8 if self.width < minwidth or self.width > maxwidth: raise FieldBoundsError, "NexthopField must be between %d " \ "and %d bytes wide" % (minwidth, maxwidth) def __eq__(self, other): """Test two NexthopFields for equality.""" if other is None: return False if self.len.value == other.type.value and \ self.flags.value == other.auxdatalen.value and \ self.hops.value == other.nsources.value and \ self.ifindex.value == other.group.value: # TODO Also compare sub TLVs. return True return False def __ne__(self, other): return not self.__eq__(other) def default_compare(lp, lf, rp, rf): """Default comparison method.""" return lf.__eq__(rf) default_compare = staticmethod(default_compare) class ifaddrmsg(pcs.Packet): """RFC 3549 interface address message.""" _layout = pcs.Layout() _map = None _descr = None _flag_bits = "\x01SECONDARY\x02NODAD\x03OPTIMISTIC"\ "\x05HOMEADDRESS\x06DEPRECATED"\ "\x07TENTATIVE\x08PERMANENT" def __init__(self, bytes = None, timestamp = None, **kv): family = pcs.Field("family", 8) prefixlen = pcs.Field("pad00", 8) flags = pcs.Field("flags", 8) scope = pcs.Field("scope", 8) index = pcs.Field("index", 32) #tlvs = pcs.OptionListField("tlvs") pcs.Packet.__init__(self, [family, prefixlen, flags, scope, index],\ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() remaining = len(bytes) - offset # TODO demux TLVs. if self.data is None: self.data = payload.payload(bytes[offset:remaining], \ timestamp=timestamp) else: self.data = None # TODO: Parse my embedded TLVs. # XXX To decapsulate I need to know my type and address family. class ifinfomsg(pcs.Packet): """RFC 3549 interface information message.""" _layout = pcs.Layout() _map = None _descr = None _flag_bits = \ "\x01UP\x02BROADCAST\x03DEBUG\x04LOOPBACK"\ "\x05POINTOPOINT\x06NOTRAILERS\x07RUNNING"\ "\x08NOARP\x09PROMISC\x0aALLMULTI"\ "\x0bMASTER\x0cSLAVE\x0dMULTICAST"\ "\x0ePORTSEL\x0fAUTOMEDIA\x10DYNAMIC"\ "\x11LOWER_UP\x12DORMANT\x13ECHO" def __init__(self, bytes = None, timestamp = None, **kv): family = pcs.Field("family", 8) pad00 = pcs.Field("pad00", 8) type = pcs.Field("type", 16) index = pcs.Field("index", 32) flags = pcs.Field("flags", 32) change = pcs.Field("change", 32) #tlvs = pcs.OptionListField("tlvs") pcs.Packet.__init__(self, [family, pad00, type, index, flags, change],\ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() remaining = len(bytes) - offset # TODO demux TLVs. if self.data is None: self.data = payload.payload(bytes[offset:remaining], \ timestamp=timestamp) else: self.data = None class prefixmsg(pcs.Packet): """RTnetlink prefix information message. Not in RFC.""" _layout = pcs.Layout() _map = None _descr = None _flagbits = "\x01ONLINK\x02AUTOCONF" def __init__(self, bytes = None, timestamp = None, **kv): """ Define the common RTNetlink message header.""" family = pcs.Field("family", 8) pad1 = pcs.Field("pad1", 8) pad2 = pcs.Field("pad2", 16) ifindex = pcs.Field("ifindex", 32) type = pcs.Field("type", 8) len = pcs.Field("len", 8) flags = pcs.Field("flags", 8) pad3 = pcs.Field("pad3", 8) #tlvs = pcs.OptionListField("tlvs") pcs.Packet.__init__(self, [family, pad1, pad2, ifindex, type, \ len, flags, pad3], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() remaining = len(bytes) - offset if self.data is None: self.data = payload.payload(bytes[offset:remaining], \ timestamp=timestamp) else: self.data = None # TODO: Parse my embedded TLVs. # XXX To decapsulate I need to know my type and address family. class rtmsg(pcs.Packet): """RFC 3549 routing message.""" _layout = pcs.Layout() _map = None _descr = None _flag_bits = "\x09NOTIFY\x0aCLONED\x0bEQUALIZE\x0cPREFIX" def __init__(self, bytes = None, timestamp = None, **kv): """ Define the common RTNetlink message header.""" family = pcs.Field("family", 8) dst_len = pcs.Field("dst_len", 8) src_len = pcs.Field("src_len", 8) tos = pcs.Field("tos", 8) table = pcs.Field("table", 8) protocol = pcs.Field("protocol", 8) scope = pcs.Field("scope", 8) type = pcs.Field("type", 8) flags = pcs.Field("flags", 32) #tlvs = pcs.OptionListField("tlvs") pcs.Packet.__init__(self, [family, dst_len, src_len, tos, table, \ protocol, scope, type, flags], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() remaining = len(bytes) - offset # TODO demux TLVs. if self.data is None: self.data = payload.payload(bytes[offset:remaining], \ timestamp=timestamp) else: self.data = None def next(self, bytes, timestamp): """Decode next layer of encapsulation.""" #if (self.dport in udp_map.map): # return udp_map.map[self.dport](bytes, timestamp = timestamp) #if (self.sport in udp_map.map): # return udp_map.map[self.sport](bytes, timestamp = timestamp) return None def rdiscriminate(self, packet, discfieldname=None, map = nlmsg_map): """Reverse-map an encapsulated packet back to a discriminator field value. Like next() only the first match is used.""" return pcs.Packet.rdiscriminate(self, packet, "type", map) def __str__(self): """Pretty-print fields.""" s = "RTNetlink\n" #s = "Netlink " + self._descr[self._fieldnames['type']] + "\n" for fn in self._layout: f = self._fieldnames[fn.name] if fn.name == "flags": value = bsprintf(f.value, self._flag_bits) s += "%s %s\n" % (fn.name, value) else: s += "%s %s\n" % (fn.name, f.value) return s #def calc_lengths(self): pcs-0.6/pcs/packets/sctp.py0000664000175000017500000003244011255512624015532 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: SCTP Packet # # An SCTP packet is a common header followed by a set of chunks, each # chunk is its own packet wrt PCS. import pcs import pcs.packets.crc32c import pcs.packets.sctp_map import inspect import time # TODO: Add calc_length() methods. class common(pcs.Packet): """SCTP common header class""" _layout = pcs.Layout() _map = None def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" sport = pcs.Field("sport", 16) dport = pcs.Field("dport", 16) tag = pcs.Field("tag", 32) checksum = pcs.Field("checksum", 32) pcs.Packet.__init__(self, [sport, dport, tag, checksum], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None and len(bytes) > self.sizeof() ): self.data = self.next(bytes[self.sizeof():len(bytes)], discriminator = bytes[self.sizeof() + 1], timestamp = timestamp) else: self.data = None def calc_checksum(): """Calculate and store the checksum for this SCTP message. Unlike other IP transports, SCTP does *not* need to see preceding header fields when calculating the CRC32C.""" self.checksum = 0xffffffff tmpbytes = self.bytes if self._head is not None: tmpbytes += self._head.collate_following(self) self.checksum = crc32c.cksum(tmpbytes) class payload(pcs.Packet): """SCTP payload chunk class""" _layout = pcs.Layout() _map = None def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 0) reserved = pcs.Field("reserved", 5) unordered = pcs.Field("unordered", 1) beginning = pcs.Field("beginning", 1) ending = pcs.Field("ending", 1) length = pcs.Field("length", 16) tsn = pcs.Field("tsn", 32) stream_id = pcs.Field("stream_id", 16) stream_seq = pcs.Field("stream_seq", 16) ppi = pcs.Field("ppi", 32) pcs.Packet.__init__(self, [type, reserved, unordered, beginning, ending, length, tsn, stream_im, stream_seq, ppi], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None # INIT and INIT ACK are basically the same other than the type add # some parameters class init(pcs.Packet): """SCTP init or init ack chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """init or init ack chunk""" type = pcs.Field("type", 8) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16) tag = pcs.Field("tag", 32) adv_recv_win_cred = pcs.Field("adv_recv_win_cred", 32) outbound_streams = pcs.Field("outbound_streams", 16) inbound_streams = pcs.Field("inbound_streams", 16) initial_tsn = pcs.Field("initial_tsn", 32) pcs.Packet.__init__(self, [type, flags, length, tag, adv_recv_win_cred, outbound_streams, inbound_streams, initial_tsn], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class sack(pcs.Packet): """SCTP ACK chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 3) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16) cumulative_tsn_ack = pcs.Field("cumulative_tsn_ack", 32) adv_recv_win_cred = pcs.Field("adv_recv_win_cred", 32) gap_ack_blocks = pcs.Field("gap_ack_blocks", 16) duplicate_tsns = pcs.Field("duplicate_tsns", 16) pcs.Packet.__init__(self, [type, flag, length, cumulative_tsn_ack, adv_recv_win_cred, gap_ack_blocks, duplicate_tsns], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class heartbeat(pcs.Packet): """SCTP heartbeat chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 4) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16) pcs.Packet.__init__(self, [type, flags, length], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class abort(pcs.Packet): """SCTP abort chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 6) reserved = pcs.Field("reserved", 7) tag = pcs.Field("tag", 1) length = pcs.Field("length", 16) pcs.Packet.__init__(self, [type, reserved, tag, length], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class shutdown(pcs.Packet): """SCTP shutdown chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 7) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16, default = 8) cumulative_tsn = pcs.Field("cumulative_tsn", 32) pcs.Packet.__init__(self, [type, flags, length, cumulative_tsn], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class shutdown_ack(pcs.Packet): """SCTP Shutdown ACK Chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 1) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16, default = 4) pcs.Packet.__init__(self, [type, flags, length], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class operation_error(pcs.Packet): """SCTP operation error chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 9) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16) pcs.Packet.__init__(self, [type, flags, length], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class cookie_echo(pcs.Packet): """SCTP Cookie Echo Chunk""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 10) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16) pcs.Packet.__init__(self, [type, flags, length], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class cookie_ack(pcs.Packet): """SCTP Cookie ACK""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 11) flags = pcs.Field("flags", 8) length = pcs.Field("length", 16, default = 4) pcs.Packet.__init__(self, [type, flags, length], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None class shutdown_complete(pcs.Packet): """SCTP Shutodwn Complete""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """common header initialization""" type = pcs.Field("type", 8, default = 14) reserved = pcs.Field("reserved", 7) tag = pcs.Field("tag", 1) length = pcs.Field("length", 16, default = 4) pcs.Packet.__init__(self, [type, reserved, tag, length], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[0:len(bytes)], timestamp = timestamp) else: self.data = None pcs-0.6/pcs/packets/llc.py0000664000175000017500000001262011255512624015331 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe IEEE 802.2 LLC/SNAP headers. # import inspect import struct import time import pcs from pcs.packets import payload import ethernet_map # # Unnumbered LLC frame control values # LLC_UI = 0x3 LLC_UI_P = 0x13 LLC_DISC = 0x43 LLC_DISC_P = 0x53 LLC_UA = 0x63 LLC_UA_P = 0x73 LLC_TEST = 0xe3 LLC_TEST_P = 0xf3 LLC_FRMR = 0x87 LLC_FRMR_P = 0x97 LLC_DM = 0x0f LLC_DM_P = 0x1f LLC_XID = 0xaf LLC_XID_P = 0xbf LLC_SABME = 0x6f LLC_SABME_P = 0x7f # # Supervisory LLC frame control values # LLC_RR = 0x01 LLC_RNR = 0x05 LLC_REJ = 0x09 LLC_INFO = 0x00 # # Common SAPs. # LLC_8021D_LSAP = 0x42 LLC_X25_LSAP = 0x7e LLC_SNAP_LSAP = 0xaa LLC_ISO_LSAP = 0xfe # This is a case where there is more than one discriminator. class llc(pcs.Packet): """IEEE 802.2 LLC""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): dsap = pcs.Field("dsap", 8) ssap = pcs.Field("ssap", 8) control = pcs.Field("control", 8) # snd_x2 in an I-frame. opt = pcs.OptionListField("opt") pcs.Packet.__init__(self, [dsap, ssap, opt], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset # TODO: Decode other fields. # For now, just do the minimum to parse 802.11 and 802.1d frames. if self.ssnap == LLC_8021D_LSAP and \ self.dsnap == LLC_8021D_LSAP and \ self.control == LLC_UI: from ieee8021d import bpdu self.data = bpdu(bytes[curr:remaining], timestamp = timestamp) elif self.ssnap == LLC_SNAP_LSAP and \ self.dsnap == LLC_SNAP_LSAP and \ self.control == LLC_UI and remaining <= 3: oui = pcs.StringField("oui", 24, default=bytes[curr:curr+3]) curr += 3 remaining -= 3 if oui.value == "\x00\x00\x00" and remaining <= 2: etype = pcs.Field("etype", 16, bytes[curr:curr+2], discriminator=True) # XXX curr += 2 remaining -= 2 self.data = self.next(bytes[curr:remaining], \ timestamp = timestamp) if self.data is None: self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None def next(self, bytes, timestamp): """Decapsulate Ethernet SNAP header.""" oui = None etype = None for o in self.opt._options: if o.name == 'oui': oui = o.value if o.name == 'etype': etype = o.value if oui is not None and etype is not None: break if oui is not None and oui.value == "\x00\x00\x00" and \ etype is not None: return ethernet_map.map[etype](bytes, timestamp=timestamp) return None def has_i_bit(dsap): return ((dsap & 0x80) == 0x80) def has_g_bit(dsap): return not has_i_bit(ssap) def has_c_bit(ssap): return ((ssap & 0x80) == 0x80) def has_r_bit(ssap): return not has_c_bit(ssap) def is_individual(self): return has_i_bit(self.dsap) def is_group(self): return has_g_bit(self.dsap) def is_command(self): return has_c_bit(self.ssap) def is_response(self): return has_r_bit(self.ssap) has_i_bit = staticmethod(has_i_bit) has_g_bit = staticmethod(has_g_bit) has_c_bit = staticmethod(has_c_bit) has_r_bit = staticmethod(has_r_bit) pcs-0.6/pcs/packets/dhcpv4.py0000664000175000017500000001556111255512624015756 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson # Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: dhcpv4.py,v 1.4 2006/06/27 14:45:43 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class implementing a DHCPv4 packet (RFC 951, RFC 2132). # import sys sys.path.append("../src") import inspect import pcs import struct import time from socket import inet_ntop #from pcs.packets.ethernet import ether_btoa from pcs.packets import payload import dhcpv4_options # BOOTP opcodes. BOOTREQUEST = 1 BOOTREPLY = 2 # BOOTP flags. BOOTP_BROADCAST = 0x8000 # Hardware address types. HTYPE_ETHER = 1 HTYPE_IEEE802 = 2 HTYPE_FDDI = 8 # MUST be present if BOOTP vendor options or DHCP is in use. DHCP_OPTIONS_COOKIE = 0x63825363 # DHCP 'special' options, used to pad or mark end of options. DHO_PAD = 0 DHO_END = 255 class dhcpv4(pcs.Packet): _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """Initialize a DHCPv4 packet. """ op = pcs.Field("op", 8) htype = pcs.Field("htype", 8) hlen = pcs.Field("hlen", 8) hops = pcs.Field("hops", 8) xid = pcs.Field("xid", 32) secs = pcs.Field("secs", 16) flags = pcs.Field("flags", 16) ciaddr = pcs.Field("ciaddr", 32) yiaddr = pcs.Field("yiaddr", 32) siaddr = pcs.Field("siaddr", 32) giaddr = pcs.Field("giaddr", 32) chaddr = pcs.StringField("chaddr", 16*8) sname = pcs.StringField("sname", 64*8) file = pcs.StringField("file", 128*8) options = pcs.OptionListField("options") pcs.Packet.__init__(self, [op, htype, hlen, hops, xid, \ secs, flags, \ ciaddr, yiaddr, siaddr, giaddr, \ chaddr, sname, file, options], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # Always point beyond the static payload so that we take the # correct slice as a vanilla payload iff no options are parsed. curr = self.sizeof() #print "self.sizeof() %d\n" % curr if bytes is not None: opts_off = curr end = len(bytes) if (end - curr) > 4: # If the DHCP cookie is present, we append it to the # options list so it will be reflected if we re-encode. # If it is not present, we set the remaining counter to 0 # so that the options list loop will not execute. cval = struct.unpack('!L', bytes[curr:curr+4])[0] if cval == DHCP_OPTIONS_COOKIE: options.append(pcs.Field("cookie", 32, default = cval)) curr += 4 else: end = 0 while curr < end: option = struct.unpack('!B', bytes[curr])[0] # Special-case options which have only a type field # and no data or length field. if option == DHO_PAD: # pad # Chew adjacent bytes into a single field. ps = curr pc = ps while pc < end: pb = struct.unpack('!B', bytes[pc])[0] if pb != 0: break pc += 1 padlen = pc - ps #print "got %d pad bytes\n" % (padlen) options.append(pcs.Field("pad", padlen * 8)) curr += padlen continue elif option == DHO_END: # end options.append(pcs.Field("end", 8, default = option)) curr += 1 continue # All DHCP options have a type byte, a length byte, # and a payload. The length byte does NOT include # the length of the other fields. curr += 1 optlen = struct.unpack('!B', bytes[curr:curr+1])[0] if (optlen < 1 or ((curr + optlen) > end)): raise UnpackError, \ "Bad length %d for DHCPv4 option %d" % \ (optlen, option) # Attempt to parse this DHCP option. # Note well: unlike TCP and IP options, the length field # in a DHCP option field does not include the length # and type bytes. # The map contains functions which take the option # list and byte array as parameters, and return a # reference to a class which wraps that option. All # are derived from a base class containing the generic # option parsing logic. # TODO: Use this technique for IGMP, IP and TCP options. curr += 1 optinst = None if option in dhcpv4_options.map: optinst = \ dhcpv4_options.map[option](option, \ bytes[curr:curr+optlen]) else: optinst = \ dhcpv4_options.tlv_option(option, \ bytes[curr:curr+optlen]) options.append(optinst.field()) curr += optlen if bytes is not None and curr < len(bytes): self.data = payload.payload(bytes[curr:len(bytes)]) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0.""" retval = "DHCP\n" for field in self._layout: retval += "%s %s\n" % (field.name, field.value) return retval def pretty(self, attr): """Pretty print address fields. """ if attr == "ciaddr" or attr == "yiaddr" or \ attr == "siaddr" or attr == "giaddr": return inet_ntop(AF_INET, struct.pack('!L', getattr(self,attr))) #elif attr == "chaddr" and self.htype == HTYPE_ETHER: # return ether_btoa(getattr(self, attr)) pcs-0.6/pcs/packets/sctp_map.py0000664000175000017500000000321611255512624016366 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: A mapping of SCTP port numbers to higher level protocols map = {} pcs-0.6/pcs/packets/bgp.py0000664000175000017500000001535611255512624015340 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: RFC 4271 Border Gateway Protocol version 4 # import inspect import struct import time import pcs import pcs.packets.payload # TODO: Add capabilities to OPEN. # TODO: Parse variable length fields in UPDATE. # TODO: Finish off TLVs. # TODO: Add error subcodes. # TODO: Add AS-path parser. # TODO: Add 32-bit AS support. # TODO: Add MPLS label support to NLRI. (RFC 3107) OPEN = 1 UPDATE = 2 NOTIFICATION = 3 KEEPALIVE = 4 HEADER_ERROR = 1 OPEN_ERROR = 2 UPDATE_ERROR = 3 HOLD_TIMER_EXPIRED = 4 FSM_ERROR = 5 CEASE = 6 class notification(pcs.Packet): """RFC 4271 BGP NOTIFICATION message.""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): code = pcs.Field("code", 8) subcode = pcs.Field("subcode", 8) opt = pcs.OptionListField("opt") pcs.Packet.__init__(self, [ code, subcode, opt ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset if remaining > 0: value = pcs.StringField("data", remaining*8, \ default=bytes[curr:remaining]) opt._options.append(value) else: self.data = None # where the meat is. lotsa tlvs. class update(pcs.Packet): """RFC 4271 BGP UPDATE message.""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): nwithdrawn = pcs.Field("nwithdrawn", 16) withdrawn = pcs.OptionListField("withdrawn") npathattrs = pcs.Field("npathattrs", 16) pathattrs = pcs.OptionListField("pathattrs") nlri = pcs.OptionListField("nlri") pcs.Packet.__init__(self, [ nwithdrawn, withdrawn, npathattrs, \ pathattrs, nlri ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = nwithdrawn.width curr = offset remaining = len(bytes) - offset # TODO parse withdrawn # TODO parse pathattrs # TODO parse nlri if remaining > 0: self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None class open(pcs.Packet): """RFC 4271 BGP OPEN message.""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): version = pcs.Field("version", 8, default=4) asnum = pcs.Field("asnum", 16) holdtime = pcs.Field("holdtime", 16) id = pcs.Field("id", 32) optlen = pcs.Field("optlen", 8) opt = pcs.OptionField("opt") pcs.Packet.__init__(self, \ [ version, asnum, holdtime, id, optlen, opt], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # TODO: Parse the Capabilities TLV (RFC 3392). if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset if optlen > 0 and remaining == optlen: opt._options.append(pcs.StringField("opts", optlen*8, \ bytes[curr:curr+optlen])) curr += optlen remaining -= optlen if remaining > 0: self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None _map = { OPEN: open, UPDATE: update, NOTIFICATION: notification # keepalive is just a plain header. } class header(pcs.Packet): """RFC 4271 BGP message header.""" _layout = pcs.Layout() _marker = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"\ "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" def __init__(self, bytes = None, timestamp = None, **kv): marker = pcs.StringField("marker", 16 * 8, default=_marker) length = pcs.Field("length", 16) type = pcs.Field("type", 8, discriminator=True) pcs.Packet.__init__(self, [ marker, length, type ], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset self.data = self.next(bytes[curr:remaining], \ timestamp = timestamp) if self.data is None: self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None pcs-0.6/pcs/packets/radiotap.py0000664000175000017500000002214711255512624016367 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the names of the author(s) or names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: Bruce M. Simpson # # Description: The Ethernet packet class import pcs import pcs.packets.payload #import pcs.packets.ieee80211 #notyet import inspect import struct import time # TODO: Move this into pcap.pyx. DLT_IEEE802_11_RADIO = 127 # 802.11 with radiotap in front # # radiotap TLV IDs. # # The tag is effectively in the header field 'present', the # lengths are not encoded in the packet; the values appear in # order according to the ordinal value of each bit. # IEEE80211_RADIOTAP_TSFT = 0 IEEE80211_RADIOTAP_FLAGS = 1 IEEE80211_RADIOTAP_RATE = 2 IEEE80211_RADIOTAP_CHANNEL = 3 IEEE80211_RADIOTAP_FHSS = 4 IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5 IEEE80211_RADIOTAP_DBM_ANTNOISE = 6 IEEE80211_RADIOTAP_LOCK_QUALITY = 7 IEEE80211_RADIOTAP_TX_ATTENUATION = 8 IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9 IEEE80211_RADIOTAP_DBM_TX_POWER = 10 IEEE80211_RADIOTAP_ANTENNA = 11 IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12 IEEE80211_RADIOTAP_DB_ANTNOISE = 13 IEEE80211_RADIOTAP_XCHANNEL = 18 IEEE80211_RADIOTAP_EXT = 31 # # IEEE80211_RADIOTAP_CHANNEL TLV contents. # IEEE80211_CHAN_TURBO = 0x00010 IEEE80211_CHAN_CCK = 0x00020 IEEE80211_CHAN_OFDM = 0x00040 IEEE80211_CHAN_2GHZ = 0x00080 IEEE80211_CHAN_5GHZ = 0x00100 IEEE80211_CHAN_PASSIVE = 0x00200 IEEE80211_CHAN_DYN = 0x00400 IEEE80211_CHAN_GFSK = 0x00800 IEEE80211_CHAN_GSM = 0x01000 IEEE80211_CHAN_STURBO = 0x02000 IEEE80211_CHAN_HALF = 0x04000 IEEE80211_CHAN_QUARTER = 0x08000 IEEE80211_CHAN_HT20 = 0x10000 IEEE80211_CHAN_HT40U = 0x20000 IEEE80211_CHAN_HT40D = 0x40000 # # IEEE80211_RADIOTAP_FLAGS TLV contents. # IEEE80211_RADIOTAP_F_CFP = 0x01 IEEE80211_RADIOTAP_F_SHORTPRE = 0x02 IEEE80211_RADIOTAP_F_WEP = 0x04 IEEE80211_RADIOTAP_F_FRAG = 0x08 IEEE80211_RADIOTAP_F_FCS = 0x10 IEEE80211_RADIOTAP_F_DATAPAD = 0x20 IEEE80211_RADIOTAP_F_BADFCS = 0x40 IEEE80211_RADIOTAP_F_SHORTGI = 0x80 # To assist in printing CHANNEL and XCHANNEL. channel_bits = "\x05TURBO\x06CCK\x07OFDM\x082GHZ"\ "\x095GHZ\x0aPASSIVE\x0bDYN\x0cGFSK"\ "\x0dGSM\x0eSTURBO\x0fHALF\x10QUARTER"\ "\x11HT20\x12HT40U\x13HT40D" # To assist in printing FLAGS. flag_bits = "\x01CFP\x02SHORTPRE\x03WEP"\ "\x04FRAG\x05FCS\x06DATAPAD"\ "\x07BADFCS\x08SHORTGI" def _channel(n, x): """Given a tuple returned by struct.unpack(), produce a list of decoded fields for a CHANNEL TLV.""" assert isinstance(n, str) assert isinstance(x, tuple) ret = [] ret += pcs.Field("chan_mhz", 8, default=x[0]) ret += pcs.Field("chan_flags", 8, default=x[1]) return ret def _xchannel(n, x): """Given a tuple returned by struct.unpack(), produce a list of decoded fields for an XCHANNEL TLV.""" assert isinstance(n, str) assert isinstance(x, tuple) ret = [] ret += pcs.Field("xchan_flags", 32, default=x[0]) ret += pcs.Field("xchan_mhz", 16, default=x[1]) ret += pcs.Field("xchan_num", 8, default=x[2]) ret += pcs.Field("xchan_hdbm", 8, default=x[3]) return ret # # bitvalue: ( name1st, bitwidth, packfmt, makefieldfunc ) # # XXX TODO: Force little-endian conversion if writing fields. # _vmap = { IEEE80211_RADIOTAP_TSFT: \ ( "tsft", 64, '> 3 vfmt = vt[2] vfunc = vt[3] if remaining >= vbytes: value = struct.unpack(vfmt, bytes[curr:vlen]) fields = vfunc(vname, value) for f in fields: tlvs._options.append(f) curr += vlen remaining -= vlen else: break # XXX TODO: always decode next header as a full 802.11 header. self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" s = self._descr[self.type] + "\n" for fn in self._layout: f = self._fieldnames[fn.name] if fn.name == "present": bs = bsprintf(f.value, self._bits) retval += "%s %s\n" % (fn.name, bs) else: retval += "%s %s\n" % (fn.name, f.value) return retval pcs-0.6/pcs/packets/http.py0000664000175000017500000000545211255512624015543 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: tcp.py,v 1.5 2006/07/06 09:31:57 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class that describes a TCP packet. import pcs import time import inspect class http(pcs.Packet): """HTTP""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize a TCP packet""" # XXX: Right now we just have a 64K request. Need to augment # from the RFC as this gets fleshed out. if bytes is None: request = pcs.StringField("request", 65535*8) else: request = pcs.StringField("request", len(bytes)*8) pcs.Packet.__init__(self, [request], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0.""" retval = "HTTP\n" for field in self._layout: retval += "%s %s\n" % (field.name, field.value) return retval def pretty(self, attr): """Pretty prting a field""" pass pcs-0.6/pcs/packets/tcp_map.py0000664000175000017500000000341711255512624016206 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: A mapping of TCP port numbers to higher level protocols #import ymsg_hdr import http #ymsg_port = 5050 http_port = 80 https_port = 43 map = {http_port: http.http, https_port: http.http} pcs-0.6/pcs/packets/udpv4.py0000664000175000017500000000616511255512624015630 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: udpv4.py,v 1.1 2005/10/14 00:53:16 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class which implements UDP v4 packets import sys sys.path.append("../src") import pcs import pcs.packets.udp class udpv4(pcs.packets.udp.udp): _layout = pcs.Layout() _map = None def __init__(self, bytes = None, timestamp = None, **kv): """Initialize a UDP packet for IPv4""" pcs.packets.udp.udp.__init__(self, bytes, timestamp, **kv) def cksum(self, ip, data = ""): """Calculate the checksum for this UDPv4 header, outside of a chain.""" from socket import IPPROTO_UDP from pcs.packets.ipv4 import ipv4 from pcs.packets.ipv4 import pseudoipv4 tmpip = pseudoipv4() tmpip.src = ip.src tmpip.dst = ip.dst tmpip.protocol = IPPROTO_UDP tmpip.length = len(self.getbytes()) + len(data) tmpbytes = tmpip.getbytes() + self.getbytes() + data return ipv4.ipv4_cksum(tmpbytes) def calc_checksum(self): """Calculate and store the checksum for this UDPv4 datagram. The packet must be part of a chain. udpv4 is a specialization of udp whose outer header must always be ipv4, therefore we enforce this.""" from pcs.packets.ipv4 import ipv4 ip = None if self._head is not None: ip = self._head.find_preceding(self, pcs.packets.ipv4.ipv4) if ip is None: self.checksum = 0 self.checksum = ipv4.ipv4.ipv4_cksum(self.getbytes()) return pcs.packets.udp.udp.calc_checksum_v4(self, ip) pcs-0.6/pcs/packets/null.py0000664000175000017500000000527011255512624015534 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: tcp.py,v 1.5 2006/07/06 09:31:57 gnn Exp $ # # Author: George V. Neville-Neil # # Description: The most generic possible PCS packet class. import pcs import inspect import time class null(pcs.Packet): """NULL.""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize a TCP packet""" null = pcs.StringField("null", 80*8) pcs.Packet.__init__(self, [null], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes, timestamp = timestamp) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0.""" retval = "NULL\n" for field in self._layout: retval += "%s %s\n" % (field.name, field.value) return retval def pretty(self, attr): """Pretty prting a field""" pass pcs-0.6/pcs/packets/udpv6.py0000664000175000017500000000626611255512624015634 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: udpv6.py,v 1.1 2006/07/06 09:31:57 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class which implements UDP v6 packets import sys sys.path.append("../src") import pcs import pcs.packets.udp class udpv6(pcs.packets.udp.udp): _layout = pcs.Layout() _map = None def __init__(self, bytes = None, timestamp = None, **kv): """Initialize a UDP packet for IPv6""" pcs.packets.udp.udp.__init__(self, bytes, timestamp, **kv) def cksum(self, ip, data = "", nx = 0): """Calculate the checksum for this UDPv6 header, outside of any existing chain.""" from pcs.packets.ipv4 import ipv4 from pcs.packets.pseudoipv6 import pseudoipv6 p6 = pseudoipv6() p6.src = ip.src p6.dst = ip.dst p6.length = len(self.getbytes()) + len(data) if nx: p6.next_header = nx else: p6.next_header = ip.next_header tmpbytes = p6.getbytes() + self.getbytes() + data return ipv4.ipv4_cksum(tmpbytes) def calc_checksum(self): """Calculate and store the checksum for this UDPv6 datagram. The packet SHOULD be part of a chain, and have an IPv6 header. udpv6 is a specialization of udp whose outer header must always be ipv4, therefore we enforce this.""" from pcs.packets.ipv4 import ipv4 ip6 = None if self._head is not None: ip6 = self._head.find_preceding(self, pcs.packets.ipv6.ipv6) if ip6 is None: self.checksum = 0 self.checksum = ipv4.ipv4_cksum(self.getbytes()) return pcs.packets.udp.udp.calc_checksum_v6(self, ip6) pcs-0.6/pcs/packets/rtp.py0000664000175000017500000001434411255512624015371 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe RFC 3550 RTP packets. # import inspect import struct import time import pcs from pcs.packets import payload #import rtp_map # TODO: Make sender header inherit from rtcp as it needs # to see the Report Count. # TODO: RTCP BYE, APP, SDES. # TODO: SDES: CNAME, NAME, EMAIL, PHONE, LOC, TOOL, NOTE, PRIV TLVs. # TODO: Sender report blocks. # TODO: Receiver reports. class rtp(pcs.Packet): """RFC 3550 Real Time Protocol""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): v = pcs.Field("v", 2) # version p = pcs.Field("p", 1) # padded x = pcs.Field("x", 1) # extended cc = pcs.Field("cc", 4) # csrc count m = pcs.Field("m", 4) # m-bit pt = pcs.Field("pt", 7, discriminator=True) # payload type seq = pcs.Field("seq", 16) # sequence ssrc = pcs.Field("ssrc", 32) # source opt = pcs.OptionListField("opt") # optional fields pcs.Packet.__init__(self, [v, p, x, cc, m, pt, seq, ssrc, opt], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset # Parse CSRC. nc = self.cc while nc > 0 and remaining >= 4: value = struct.unpack("!I", bytes[curr:curr+4]) csrc = pcs.Field("csrc", 32, default=value) self.opt._options.append(csrc) curr += 4 remaining -= 4 # Parse Header Extension. if self.x == 1 and remaining >= 4: extlen = struct.unpack("!H", bytes[curr+2:curr+4]) extlen <<= 2 extlen = min(extlen, remaining) # Copy the entire chunk so we keep the type field. ext = pcs.StringField("ext", extlen * 8, \ default=bytes[curr:extlen+4]) self.opt._options.append(ext) curr += extlen remaining -= extlen # Heed padding byte. npad = 0 if self.p == 1: npad = bytes[-1] self.data = payload.payload(bytes[curr:remaining-npad], \ timestamp = timestamp) else: self.data = None #def next(self, bytes, timestamp): # """Decapsulate RTP payload header according to payload type.""" class rtcp(pcs.Packet): """RFC 3550 Real Time Control Protocol header""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): v = pcs.Field("v", 2) p = pcs.Field("p", 1) rc = pcs.Field("rc", 5) pt = pcs.Field("pt", 8) length = pcs.Field("length", 16) ssrc = pcs.Field("ssrc", 32) pcs.Packet.__init__(self, [v, p, rc, pt, length, ssrc], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset # XXX TODO look at pt and decapsulate next. self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None class sender(pcs.Packet): """RFC 3550 Real Time Control Protocol sender message portion""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): ntpts = pcs.Field("ntpts", 64) rtpts = pcs.Field("rtpts", 32) spkts = pcs.Field("spkts", 32) sbytes = pcs.Field("sbytes", 32) opt = pcs.OptionListField("opt") pcs.Packet.__init__(self, [ntpts, rtpts, spkts, sbytes, opt], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset # XXX TODO decapsulate all the report counts. # to do this, we need to see the parent RC. self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None pcs-0.6/pcs/packets/udp.py0000664000175000017500000001462711255512624015360 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: udp.py,v 1.4 2006/09/01 05:24:04 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class which implements UDP v4 packets import pcs import udp_map import inspect import socket import time class udp(pcs.Packet): """UDP""" _layout = pcs.Layout() _map = None def __init__(self, bytes = None, timestamp = None, **kv): """initialize a UDP packet""" sport = pcs.Field("sport", 16) dport = pcs.Field("dport", 16) length = pcs.Field("length", 16) checksum = pcs.Field("checksum", 16) pcs.Packet.__init__(self, [sport, dport, length, checksum], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[8:len(bytes)], timestamp) else: self.data = None # XXX UDP MUST have its own next() and rdiscriminate() functions, # so that it can discriminate on either sport or dport. def next(self, bytes, timestamp): """Decode higher level services.""" if (self.dport in udp_map.map): return udp_map.map[self.dport](bytes, timestamp = timestamp) if (self.sport in udp_map.map): return udp_map.map[self.sport](bytes, timestamp = timestamp) return None def rdiscriminate(self, packet, discfieldname = None, map = udp_map.map): """Reverse-map an encapsulated packet back to a discriminator field value. Like next() only the first match is used.""" #print "reverse discriminating %s" % type(packet) result = pcs.Packet.rdiscriminate(self, packet, "dport", map) if result is False: result = pcs.Packet.rdiscriminate(self, packet, "sport", map) return result def calc_checksum(self): """Calculate and store the checksum for this UDP datagram. The packet must be part of a chain. We attempt to infer whether IPv4 or IPv6 encapsulation is in use for the payload. The closest header wins the match. The network layer header must immediately precede the UDP datagram (for now).""" from pcs.packets.ipv4 import ipv4 ip = None ip6 = None if self._head is not None: (ip, iip) = self._head.find_preceding(self, pcs.packets.ipv4.ipv4) (ip6, iip6) = self._head.find_preceding(self, pcs.packets.ipv6.ipv6) # Either this UDP header is not in a chain, or no IPv4/IPv6 # outer header was found. if ip is None and ip6 is None: self.checksum = 0 self.checksum = ipv4.ipv4_cksum(self.getbytes()) return # If we found both IPv4 and IPv6 headers then we must break the tie. # The closest outer header wins and is used for checksum calculation. if ip is not None and ip6 is not None: assert iip != iip6, "ipv4 and ipv6 cannot be at same index" if iip6 > iip: ip = None # ip6 is nearest outer header, ignore ip else: ip6 = None # ip is nearest outer header, ignore ip6 if ip is not None: self.calc_checksum_v4(ip) else: self.calc_checksum_v6(ip6) def calc_checksum_v4(self, ip): """Calculate and store the checksum for the UDP datagram when encapsulated as an IPv4 payload with the given header.""" #print "udp.calc_checksum_v4()" from pcs.packets.ipv4 import ipv4 from pcs.packets.ipv4 import pseudoipv4 self.checksum = 0 payload = self._head.collate_following(self) pip = pseudoipv4() pip.src = ip.src pip.dst = ip.dst pip.protocol = socket.IPPROTO_UDP pip.length = len(self.getbytes()) + len(payload) tmpbytes = pip.getbytes() + self.getbytes() + payload self.checksum = ipv4.ipv4_cksum(tmpbytes) def calc_checksum_v6(self, ip6): """Calculate and store the checksum for the UDP datagram when encapsulated as an IPv6 payload with the given header.""" #print "udp.calc_checksum_v6()" from pcs.packets.ipv4 import ipv4 from pcs.packets.pseudoipv6 import pseudoipv6 self.checksum = 0 payload = self._head.collate_following(self) pip6 = pseudoipv6() pip6.src = ip6.src pip6.dst = ip6.dst pip6.next_header = ip6.next_header pip6.length = len(self.getbytes()) + len(payload) tmpbytes = pip6.getbytes() + self.getbytes() + payload self.checksum = ipv4.ipv4_cksum(tmpbytes) def calc_length(self): """Calculate and store the length field(s) for this packet.""" self.length = len(self.getbytes()) if self._head is not None: self.length += len(self._head.collate_following(self)) pcs-0.6/pcs/packets/crc32c.py0000664000175000017500000001300411255512624015633 0ustar andreasandreas# # Copyright (c) 2004 Dug Song # All rights reserved, all wrongs reversed. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # 3. The names of the authors and copyright holders may not be used to # endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL # THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # $Id: crc32c.py 23 2006-11-08 15:45:33Z dugsong $ # import array # CRC-32C Checksum # http://tools.ietf.org/html/rfc3309 crc32c_table = ( 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L ) def add(crc, buf): buf = array.array('B', buf) for b in buf: crc = (crc >> 8) ^ crc32c_table[(crc ^ b) & 0xff] return crc def done(crc): tmp = ~crc & 0xffffffffL b0 = tmp & 0xff b1 = (tmp >> 8) & 0xff b2 = (tmp >> 16) & 0xff b3 = (tmp >> 24) & 0xff crc = (b0 << 24) | (b1 << 16) | (b2 << 8) | b3 return crc def cksum(buf): """Return computed CRC-32c checksum.""" return done(add(0xffffffffL, buf)) pcs-0.6/pcs/packets/nd6.py0000664000175000017500000000445011255512624015250 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: nd6.py,v 1.4 2006/06/27 14:45:43 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A set of classes for working with neighbor discovery import pcs import icmpv6 # All neighbor discovery messages are inserted in ICMPv6 packets import time class nd6_solicit(pcs.Packet): """Neighbor Discovery""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize a Neighbor Solicitaion header""" reserved = pcs.Field("reserved", 32) target = pcs.Field("target", 128) pcs.Packet.__init__(self, [reserved, target], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp pcs-0.6/pcs/packets/mtrace.py0000664000175000017500000001027011255512624016031 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: A class which describes MTRACE messages, as encapsulated # inside the payload of an IGMP type 0x1F/0x1E message. # # MTRACE is defined in draft-ietf-idmr-traceroute-ipm-07. # Typically a listener will join the 224.0.1.32 group and listen # for responses, then begin sending queries to 224.0.0.2. # Note that 224.0.1.32 is NOT a link-scope group, and # a unicast address may be used instead. # # See also draft-ietf-mboned-mtrace-v2-00 which uses UDP (published # 12 Nov 2007 and not yet widely implemented). SSMPING is a similar # tool in intent and use. # import inspect import pcs import struct import time from pcs.packets import payload from socket import AF_INET, inet_ntop, inet_ntoa class query(pcs.Packet): layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize the MTRACE query header.""" # (G,S) tuple to query. group = pcs.Field("group", 32) source = pcs.Field("source", 32) # Who's asking. receiver = pcs.Field("receiver", 32) # Where to send the answer. response_addr = pcs.Field("response_addr", 32) response_hoplimit = pcs.Field("response_hoplimit", 8) # The ID of this query. query_id = pcs.Field("query_id", 24) pcs.Packet.__init__(self, [group, source, \ receiver, response_addr, \ response_hoplimit, query_id], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None class reply(pcs.Packet): layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize the MTRACE response header.""" # (G,S) tuple to query. group = pcs.Field("group", 32) source = pcs.Field("source", 32) # Who's asking. receiver = pcs.Field("receiver", 32) # Where to send the answer. response_addr = pcs.Field("response_addr", 32) response_hoplimit = pcs.Field("response_hoplimit", 8) # The ID of this query. query_id = pcs.Field("query_id", 24) #...hops? pcs.Packet.__init__(self, [group, source, \ receiver, response_addr, \ response_hoplimit, query_id], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None pcs-0.6/pcs/packets/ipcomp.py0000664000175000017500000000452511255512624016053 0ustar andreasandreas# Copyright (c) 2006, Clément Lecigne # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id $ # # Author: Clément Lecigne # # Description: A class which implements IP payload Compression packets import pcs #socket module already defines it. #IPPROTO_IPCOMP = 108 class ipcomp(pcs.Packet): _layout = pcs.Layout() def __init__(self, bytes = None, **kv): "A class that contains the IPComp header. RFC3173" nx = pcs.Field("next_header", 8) flags = pcs.Field("flags", 8) cpi = pcs.Field("cpi", 16) pcs.Packet.__init__(self, [nx, flags, cpi], bytes = bytes, **kv) def __str__(self): """Walk the entire packet and pretty print the values of the fields. Addresses are printed if and only if they are set and not 0.""" retval = "" for field in self._layout: retval += "%s %d\n" % (field.name, field.value) return retval pcs-0.6/pcs/packets/icmpv4.py0000664000175000017500000001624211255512624015765 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: icmpv4.py,v 1.7 2006/09/05 07:30:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class which describes an ICMPv4 packet import pcs import inspect import time # # ICMP types. # ICMP_ECHOREPLY = 0 # echo reply ICMP_UNREACH = 3 # dest unreachable, codes: ICMP_SOURCEQUENCH = 4 # packet lost, slow down ICMP_REDIRECT = 5 # shorter route ICMP_ALTHOSTADDR = 6 # alternate host address ICMP_ECHO = 8 # echo service ICMP_ROUTERADVERT = 9 # router advertisement ICMP_ROUTERSOLICIT = 10 # router solicitation ICMP_TIMXCEED = 11 # time exceeded, code: ICMP_PARAMPROB = 12 # ip header bad ICMP_TSTAMP = 13 # timestamp request ICMP_TSTAMPREPLY = 14 # timestamp reply ICMP_IREQ = 15 # information request ICMP_IREQREPLY = 16 # information reply ICMP_MASKREQ = 17 # address mask request ICMP_MASKREPLY = 18 # address mask reply ICMP_TRACEROUTE = 30 # traceroute ICMP_DATACONVERR = 31 # data conversion error ICMP_MOBILE_REDIRECT = 32 # mobile host redirect ICMP_IPV6_WHEREAREYOU = 33 # IPv6 where-are-you ICMP_IPV6_IAMHERE = 34 # IPv6 i-am-here ICMP_MOBILE_REGREQUEST = 35 # mobile registration req ICMP_MOBILE_REGREPLY = 36 # mobile registration reply ICMP_SKIP = 39 # SKIP ICMP_PHOTURIS = 40 # Photuris # # ICMP codes. # ICMP_UNREACH_NET = 0 # bad net ICMP_UNREACH_HOST = 1 # bad host ICMP_UNREACH_PROTOCOL = 2 # bad protocol ICMP_UNREACH_PORT = 3 # bad port ICMP_UNREACH_NEEDFRAH = 4 # IP_DF caused drop ICMP_UNREACH_SRCFAIL = 5 # src route failed ICMP_UNREACH_NET_UNKNOWN = 6 # unknown net ICMP_UNREACH_HOST_UNKNOWN = 7 # unknown host ICMP_UNREACH_ISOLATED = 8 # src host isolated ICMP_UNREACH_NET_PROHIB = 9 # prohibited access ICMP_UNREACH_HOST_PROHIB = 10 # ditto ICMP_UNREACH_TOSNET = 11 # bad tos for net ICMP_UNREACH_TOSHOST = 12 # bad tos for host ICMP_UNREACH_FILTER_PROHIB = 13 # admin prohib ICMP_UNREACH_HOST_PRECEDENCE = 14 # host prec vio. ICMP_UNREACH_PRECEDENCE_CUTOFF = 1 # prec cutoff ICMP_REDIRECT_NET = 0 # for network ICMP_REDIRECT_HOST = 1 # for host ICMP_REDIRECT_TOSNET = 2 # for tos and net ICMP_REDIRECT_TOSHOST = 3 # for tos and host ICMP_ROUTERADVERT_NORMAL = 0 # normal advertisement ICMP_ROUTERADVERT_NOROUTE_COMMON = 1 # selective routing ICMP_TIMXCEED_INTRANS = 0 # ttl==0 in transit ICMP_TIMXCEED_REASS = 1 # ttl==0 in reass ICMP_PARAMPROB_ERRATPTR = 0 # error at param ptr ICMP_PARAMPROB_OPTABSENT = 1 # req. opt. absent ICMP_PARAMPROB_LENGTH = 2 # bad length ICMP_PHOTURIS_UNKNOWN_INDEX = 1 # unknown sec index ICMP_PHOTURIS_AUTH_FAILED = 2 # auth failed ICMP_PHOTURIS_DECRYPT_FAILED = 3 # decrypt failed class icmpv4echo(pcs.Packet): """ICMPv4 Echo""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize an ICMPv4 echo packet, used by ping(8) and others""" id = pcs.Field("id", 16) seq = pcs.Field("sequence", 16) pcs.Packet.__init__(self, [id, seq], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() from pcs.packets import payload self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None # Gnarly: Python can't forward declare, and this module depends upon # things being defined in a certain order. icmp_map = { ICMP_ECHOREPLY: icmpv4echo, ICMP_ECHO: icmpv4echo } descr = { ICMP_ECHOREPLY: "ICMPv4 Echo Reply", ICMP_ECHO: "ICMPv4 Echo Request" } class icmpv4(pcs.Packet): """ICMPv4""" _layout = pcs.Layout() _map = icmp_map _descr = descr def __init__(self, bytes = None, timestamp = None, **kv): """initialize a ICMPv4 packet""" type = pcs.Field("type", 8, discriminator=True) code = pcs.Field("code", 8) cksum = pcs.Field("checksum", 16) pcs.Packet.__init__(self, [type, code, cksum], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() # XXX Workaround Packet.next() -- it only returns something # if it can discriminate. self.data = self.next(bytes[offset:len(bytes)], timestamp = timestamp) if self.data is None: from pcs.packets.payload import payload self.data = payload(bytes[offset:len(bytes)]) else: self.data = None def calc_checksum(self): """Calculate and store the checksum for this ICMP header. ICMP checksums are computed over payloads, but not IP headers.""" self.checksum = 0 tmpbytes = self.getbytes() if not self._head is None: tmpbytes += self._head.collate_following(self) from pcs.packets.ipv4 import ipv4 self.checksum = ipv4.ipv4_cksum(tmpbytes) def rdiscriminate(self, packet, discfieldname = None, map = icmp_map): """Reverse-map an encapsulated packet back to a discriminator field value. Like next() only the first match is used.""" print "reverse discriminating %s" % type(packet) return pcs.Packet.rdiscriminate(self, packet, "type", map) def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" retval = self._descr[self.type] + "\n" for field in self._layout: retval += "%s %s\n" % (field.name, field.value) return retval pcs-0.6/pcs/packets/bsdrtmsg.py0000664000175000017500000005243211255512624016411 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe BSD routing socket messages. # import inspect import struct import time import pcs import payload #from socket import AF_INET, inet_ntop, inet_ntoa # TODO: Add __str__ and __repr__ methods to objects which contain # structured addresses. # TODO: Deal with BSD routing socket address padding. These are handled # in a very specific way. # TODO: Deal with structure padding and architecture specific fields # correctly. # TODO: Test all this. # # Current FreeBSD routing socket version. # RTM_VERSION = 5 # # Size of an interface name, always fixed. # IFNAMSIZ = 16 # # Route flags # RTF_UP = 0x1 # route usable RTF_GATEWAY = 0x2 # destination is a gateway RTF_HOST = 0x4 # host entry (net otherwise) RTF_REJECT = 0x8 # host or net unreachable RTF_DYNAMIC = 0x10 # created dynamically (by redirect) RTF_MODIFIED = 0x20 # modified dynamically (by redirect) RTF_DONE = 0x40 # message confirmed RTF_CLONING = 0x100 # generate new routes on use RTF_XRESOLVE = 0x200 # external daemon resolves name RTF_LLINFO = 0x400 # generated by link layer (e.g. ARP) RTF_STATIC = 0x800 # manually added RTF_BLACKHOLE = 0x1000 # just discard pkts (during updates) RTF_PROTO2 = 0x4000 # protocol specific routing flag RTF_PROTO1 = 0x8000 # protocol specific routing flag RTF_PRCLONING = 0x10000 # unused, for compatibility RTF_WASCLONED = 0x20000 # route generated through cloning RTF_PROTO3 = 0x40000 # protocol specific routing flag RTF_PINNED = 0x100000 # future use RTF_LOCAL = 0x200000 # route represents a local address RTF_BROADCAST = 0x400000 # route represents a bcast address RTF_MULTICAST = 0x800000 # route represents a mcast address # # Message types. # RTM_ADD = 0x1 # Add Route RTM_DELETE = 0x2 # Delete Route RTM_CHANGE = 0x3 # Change Metrics or flags RTM_GET = 0x4 # Report Metrics RTM_LOSING = 0x5 # Kernel Suspects Partitioning RTM_REDIRECT = 0x6 # Told to use different route RTM_MISS = 0x7 # Lookup failed on this address RTM_LOCK = 0x8 # fix specified metrics RTM_OLDADD = 0x9 # caused by SIOCADDRT RTM_OLDDEL = 0xa # caused by SIOCDELRT RTM_RESOLVE = 0xb # req to resolve dst to LL addr RTM_NEWADDR = 0xc # address being added to iface RTM_DELADDR = 0xd # address being removed from iface RTM_IFINFO = 0xe # iface going up/down etc. RTM_NEWMADDR = 0xf # mcast group membership being added to if RTM_DELMADDR = 0x10 # mcast group membership being deleted RTM_IFANNOUNCE = 0x11 # iface arrival/departure RTM_IEEE80211 = 0x12 # IEEE80211 wireless event # # Bitmask values for rtm_inits and rmx_locks. # RTV_MTU = 0x1 # init or lock _mtu RTV_HOPCOUNT = 0x2 # init or lock _hopcount RTV_EXPIRE = 0x4 # init or lock _expire RTV_RPIPE = 0x8 # init or lock _recvpipe RTV_SPIPE = 0x10 # init or lock _sendpipe RTV_SSTHRESH = 0x20 # init or lock _ssthresh RTV_RTT = 0x40 # init or lock _rtt RTV_RTTVAR = 0x80 # init or lock _rttvar # # Bitmask values for rtm_addrs. # RTA_DST = 0x1 # destination sockaddr present RTA_GATEWAY = 0x2 # gateway sockaddr present RTA_NETMASK = 0x4 # netmask sockaddr present RTA_GENMASK = 0x8 # cloning mask sockaddr present RTA_IFP = 0x10 # interface name sockaddr present RTA_IFA = 0x20 # interface addr sockaddr present RTA_AUTHOR = 0x40 # sockaddr for author of redirect RTA_BRD = 0x80 # for NEWADDR, broadcast or p-p dest addr # # Index offsets for sockaddr array for alternate internal encoding. # RTAX_DST = 0 # destination sockaddr present RTAX_GATEWAY = 1 # gateway sockaddr present RTAX_NETMASK = 2 # netmask sockaddr present RTAX_GENMASK = 3 # cloning mask sockaddr present RTAX_IFP = 4 # interface name sockaddr present RTAX_IFA = 5 # interface addr sockaddr present RTAX_AUTHOR = 6 # sockaddr for author of redirect RTAX_BRD = 7 # for NEWADDR, broadcast or p-p dest addr RTAX_MAX = 8 # size of array to allocate # # ifannounce "what". # IFAN_ARRIVAL = 0 # interface arrival IFAN_DEPARTURE = 1 # interface departure # # IEEE80211 "what". # RTM_IEEE80211_ASSOC = 100 # station associate (bss mode) RTM_IEEE80211_REASSOC = 101 # station re-associate (bss mode) RTM_IEEE80211_DISASSOC = 102 # station disassociate (bss mode) RTM_IEEE80211_JOIN = 103 # station join (ap mode) RTM_IEEE80211_LEAVE = 104 # station leave (ap mode) RTM_IEEE80211_SCAN = 105 # scan complete, results available RTM_IEEE80211_REPLAY = 106 # sequence counter replay detected RTM_IEEE80211_MICHAEL = 107 # Michael MIC failure detected RTM_IEEE80211_REJOIN = 108 # station re-associate (ap mode) # # BSD IFF* flags. # IFF_UP = 0x1 # (n) interface is up IFF_BROADCAST = 0x2 # (i) broadcast address valid IFF_DEBUG = 0x4 # (n) turn on debugging IFF_LOOPBACK = 0x8 # (i) is a loopback net IFF_POINTOPOINT = 0x10 # (i) is a point-to-point link IFF_SMART = 0x20 # (i) interface manages own routes IFF_DRV_RUNNING = 0x40 # (d) resources allocated IFF_NOARP = 0x80 # (n) no address resolution protocol IFF_PROMISC = 0x100 # (n) receive all packets IFF_ALLMULTI = 0x200 # (n) receive all multicast packets IFF_DRV_OACTIVE = 0x400 # (d) tx hardware queue is full IFF_SIMPLEX = 0x800 # (i) can't hear own transmissions IFF_LINK0 = 0x1000 # per link layer defined bit IFF_LINK1 = 0x2000 # per link layer defined bit IFF_LINK2 = 0x4000 # per link layer defined bit IFF_ALTPHYS = IFF_LINK2 # use alternate physical connection IFF_MULTICAST = 0x8000 # (i) supports multicast IFF_PPROMISC = 0x20000 # (n) user-requested promisc mode IFF_MONITOR = 0x40000 # (n) user-requested monitor mode IFF_STATICARP = 0x80000 # (n) static ARP IFF_NEEDSGIANT = 0x100000 # (i) hold Giant over if_start calls # # if_link_state. # LINK_STATE_UNKNOWN = 0 # link invalid/unknown LINK_STATE_DOWN = 1 # link is down LINK_STATE_UP = 2 # link is up _iff_flagbits =\ "\x01UP\x02BROADCAST\x03DEBUG\x04LOOPBACK"\ "\x04POINTOPOINT\x05SMART\x06DRV_RUNNING\x07NOARP"\ "\x08PROMISC\x09ALLMULTI\x0aDRV_OACTIVE\x0bSIMPLEX"\ "\x0cLINK0\x0dLINK1\x0eLINK2\x0fMULTICAST"\ "\x11PPROMISC\x12MONITOR\x13STATICARP\x14NEEDSGIANT" class if_link_msg(pcs.Packet): """BSD Routing socket -- link-state message (if_msghdr)""" _layout = pcs.Layout() _map = None _descr = None _flagbits = _iff_flagbits def __init__(self, bytes = None, timestamp = None, **kv): addrs = pcs.Field("addrs", 32) flags = pcs.Field("flags", 32) index = pcs.Field("index", 16) pad00 = pcs.Field("pad00", 16) # XXX very likely it's padded # XXX We don't decode if_data yet. # Its length (and widths) are arch-dependent! data = pcs.Field("data", 152 * 8) pcs.Packet.__init__(self, [addrs, flags, index, pad00, ifdata], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" s = self._descr[self.type] + "\n" for fn in self._layout: f = self._fieldnames[fn.name] if fn.name == "flags": bs = bsprintf(f.value, self._flagbits) s += "%s %s\n" % (fn.name, bs) else: s += "%s %s\n" % (fn.name, f.value) return s class if_addr_msg(pcs.Packet): """BSD Routing socket -- protocol address message (ifa_msghdr) """ _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): addrs = pcs.Field("addrs", 32) flags = pcs.Field("flags", 32) # ifa_flags, not much defined index = pcs.Field("index", 16) pad00 = pcs.Field("pad00", 16) # XXX very likely it's padded metric = pcs.Field("metric", 32) pcs.Packet.__init__(self, [addrs, flags, index, pad00, metric], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None class if_maddr_msg(pcs.Packet): """BSD Routing socket -- multicast group message (ifma_msghdr) """ _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): addrs = pcs.Field("addrs", 32) flags = pcs.Field("flags", 32) # ifa_flags, not much defined index = pcs.Field("index", 16) pcs.Packet.__init__(self, [addrs, flags, index], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None class if_state_msg(pcs.Packet): """BSD Routing socket -- interface-state message (if_announcemsghdr)""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): index = pcs.Field("index", 16) name = pcs.StringField("name", IFNAMSIZ * 8) what = pcs.Field("what", 16) pcs.Packet.__init__(self, [index, name, what], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None # # IEEE 802.11 support # class ieee80211_join_event(pcs.Packet): """BSD Routing socket -- IEEE 802.11 join event""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): address = pcs.Field("address", 6 * 8) pcs.Packet.__init__(self, [address], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None class ieee80211_leave_event(pcs.Packet): """BSD Routing socket -- IEEE 802.11 leave event""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): address = pcs.Field("address", 6 * 8) pcs.Packet.__init__(self, [address], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None class ieee80211_replay_event(pcs.Packet): """BSD Routing socket -- IEEE 802.11 replay event""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): src = pcs.Field("src", 6 * 8) dst = pcs.Field("dst", 6 * 8) cipher = pcs.Field("cipher", 8) keyid = pcs.Field("keyid", 8) keyix = pcs.Field("keyrsc", 64) rsc = pcs.Field("rsc", 64) pcs.Packet.__init__(self, [src, dst, cipher, keyid, keyix, rsc], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None class ieee80211_michael_event(pcs.Packet): """BSD Routing socket -- IEEE 802.11 MICHAEL failure event""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): src = pcs.Field("src", 6 * 8) dst = pcs.Field("dst", 6 * 8) cipher = pcs.Field("cipher", 8) keyix = pcs.Field("keyrsc", 64) pcs.Packet.__init__(self, [src, dst, cipher, keyix], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None ieee80211_map = { RTM_IEEE80211_ASSOC: ieee80211_join_event, RTM_IEEE80211_REASSOC: ieee80211_join_event, RTM_IEEE80211_DISASSOC: ieee80211_leave_event, RTM_IEEE80211_JOIN: ieee80211_join_event, RTM_IEEE80211_LEAVE: ieee80211_leave_event, RTM_IEEE80211_SCAN: payload.payload, # should be empty RTM_IEEE80211_REPLAY: ieee80211_replay_event, RTM_IEEE80211_MICHAEL: ieee80211_michael_event, RTM_IEEE80211_REJOIN: ieee80211_join_event } ieee80211_descr = { RTM_IEEE80211_ASSOC: "Associate", RTM_IEEE80211_REASSOC: "Reassociate", RTM_IEEE80211_DISASSOC: "Disassociate", RTM_IEEE80211_JOIN: "Join", RTM_IEEE80211_LEAVE: "Leave", RTM_IEEE80211_SCAN: "Scan Complete", RTM_IEEE80211_REPLAY: "Replay Detected", RTM_IEEE80211_MICHAEL: "MICHAEL Failure", RTM_IEEE80211_REJOIN: "Rejoin" } class if_ieee80211_msg(pcs.Packet): """BSD Routing socket -- IEEE 802.11 state messages (if_announcemsghdr)""" _layout = pcs.Layout() _map = ieee80211_map _descr = ieee80211_descr def __init__(self, bytes = None, timestamp = None, **kv): index = pcs.Field("index", 16) name = pcs.StringField("name", IFNAMSIZ * 8) what = pcs.Field("what", 16, discriminator=True) pcs.Packet.__init__(self, [index, name, what], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None def rdiscriminate(self, packet, discfieldname = None, map = ieee80211_map): """Reverse-map an encapsulated packet back to a discriminator field value. Like next() only the first match is used.""" return pcs.Packet.rdiscriminate(self, packet, "what", map) # # What "route -nv monitor" knows about. # class rt_msg(pcs.Packet): """BSD Routing socket -- routing message""" _layout = pcs.Layout() _map = None _descr = None _flagbits = "\x01UP\x02GATEWAY\x03HOST\x04REJECT\x05DYNAMIC"\ "\x06MODIFIED\x07DONE\x09CLONING\x0aXRESOLVE\x0bLLINFO"\ "\x0cSTATIC\x0dBLACKHOLE\x0ePROTO2\x0fPROTO1\x10PRCLONING"\ "\x11WASCLONED\x12PROTO3\x14PINNED\x15LOCAL\x16BROADCAST"\ "\x17MULTICAST" def __init__(self, bytes = None, timestamp = None, **kv): """ Define the common rtmsg header; see . """ index = pcs.Field("index", 16) flags = pcs.Field("flags", 32) addrs = pcs.Field("addrs", 32) pid = pcs.Field("pid", 32) seq = pcs.Field("seq", 32) errno = pcs.Field("errno", 32) fmask = pcs.Field("fmask", 32) inits = pcs.Field("inits", 32) # 14 * sizeof(long) on platform; arch-specific. #rmx = pcs.Field("rmx", 32) pcs.Packet.__init__(self, [index, flags, addrs, pid, seq, errno, \ fmask, inits], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" s = self._descr[self.type] + "\n" for fn in self._layout: f = self._fieldnames[fn.name] if fn.name == "flags": bs = bsprintf(f.value, self._flagbits) s += "%s %s\n" % (fn.name, bs) else: s += "%s %s\n" % (fn.name, f.value) return s # What "route -nv monitor" knows about. rtmsg_map = { # struct rtmsg_hdr RTM_ADD: rt_msg, RTM_DELETE: rt_msg, RTM_CHANGE: rt_msg, RTM_GET: rt_msg, RTM_LOSING: rt_msg, RTM_REDIRECT: rt_msg, RTM_MISS: rt_msg, RTM_LOCK: rt_msg, RTM_RESOLVE: rt_msg, # struct if_msghdr RTM_IFINFO: if_link_msg, # struct ifa_msghdr RTM_NEWADDR: if_addr_msg, RTM_DELADDR: if_addr_msg, # struct ifma_msghdr RTM_NEWMADDR: if_maddr_msg, RTM_DELMADDR: if_maddr_msg, # struct if_announcemsghdr RTM_IFANNOUNCE: if_state_msg, # struct if_announcemsghdr ('what' overloaded) RTM_IEEE80211: if_ieee80211_msg } descr = { RTM_ADD: "Added route", RTM_DELETE: "Deleted route", RTM_CHANGE: "Changed metrics or flags", RTM_GET: "Report metrics", RTM_LOSING: "Kernel suspects partitioning", RTM_REDIRECT: "Redirected", RTM_MISS: "Lookup failed", RTM_LOCK: "Fix metrics", RTM_RESOLVE: "Route cloned", RTM_IFINFO: "Link-state change", RTM_NEWADDR: "Added protocol address", RTM_DELADDR: "Removed protocol address", RTM_NEWMADDR: "Joined group", RTM_DELMADDR: "Left group", RTM_IFANNOUNCE: "Interface change", RTM_IEEE80211: "IEEE 802.11 event" } class rtmsghdr(pcs.Packet): """BSD Routing socket -- message header (common to all messages)""" _layout = pcs.Layout() _map = rtmsg_map _descr = descr def __init__(self, bytes = None, timestamp = None, **kv): """ Define the common rtmsg header; see . """ msglen = pcs.Field("msglen", 16) version = pcs.Field("version", 8, default=RTM_VERSION) type = pcs.Field("type", 8, discriminator=True) # XXX There's implicit padding all over the shop here. pad0 = pcs.Field("type", 16) pcs.Packet.__init__(self, [msglen, version, type, pad0], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: # XXX Workaround Packet.next() -- it only returns something # if it can discriminate. # XXX Should try rtmsg next, next. offset = self.sizeof() self.data = self.next(bytes[offset:len(bytes)], timestamp = timestamp) if self.data is None: self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None def rdiscriminate(self, packet, discfieldname = None, map = rtmsg_map): """Reverse-map an encapsulated packet back to a discriminator field value. Like next() only the first match is used.""" return pcs.Packet.rdiscriminate(self, packet, "type", map) def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" s = self._descr[self.type] + "\n" for field in self._layout: s += "%s %s\n" % (field.name, field.value) return s pcs-0.6/pcs/packets/payload.py0000664000175000017500000000522311255512624016211 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: A raw data class for PCS. This contains only data, and # nothing else. It is the catch all for data that is not known. import pcs from pprint import pformat import inspect import time class payload(pcs.Packet): """Payload""" _layout = pcs.Layout() _map = None def __init__(self, bytes = None, timestamp = None, **kv): """initialize a payload packet""" if bytes is None: pl = kv['payload'] payload = pcs.StringField("payload", len(pl) * 8, default=pl) else: payload = pcs.StringField("payload", len(bytes) * 8) pcs.Packet.__init__(self, [payload], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp # Unconditionally the last packet in a chain self.data = None def __str__(self): """return a readable version of a payload object""" retval = "Payload\n" retval += "%s" % pformat(self.payload) return retval pcs-0.6/pcs/packets/ethernet_map.py0000664000175000017500000000430611255512624017234 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: This is a module which maps Ethernet protocol types to # class names for use by the Ethernet class. # The map is a dictionary who's key is the protocol type and who's # value is the class constructor for that type. import ipv4, ipv6, arp ETHERTYPE_IP = 0x0800 # IP protocol ETHERTYPE_ARP = 0x0806 # Addr. resolution protocol ETHERTYPE_VLAN = 0x8100 # 802.1q header ETHERTYPE_IPV6 = 0x86dd # IPv6 ETHERTYPE_MPLS = 0x8847 # unicast ETHERTYPE_MPLS_M = 0x8848 # multicast ETHERTYPE_SLOW = 0x8809 # 802.3ad link aggregation (LACP) map = {ETHERTYPE_IP: ipv4.ipv4, ETHERTYPE_ARP: arp.arp, ETHERTYPE_IPV6: ipv6.ipv6} pcs-0.6/pcs/packets/pseudoipv6.py0000664000175000017500000000435611255512624016672 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: pseudoipv6.py,v 1.2 2006/08/01 13:35:58 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A class that implements an IPv6 packet. # import pcs import struct class pseudoipv6(pcs.Packet): """A class that create an IPv6 pseudo header used for upper-layer checksums.""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None): """IPv6 pseudo header from RFC 2460""" src = pcs.StringField("src", 16 * 8) dst = pcs.StringField("dst", 16 * 8) length = pcs.Field("length", 32) zero = pcs.Field("zero", 24) nh = pcs.Field("next_header", 8) pcs.Packet.__init__(self, [src, dst, length, zero, nh], bytes); pcs-0.6/pcs/packets/ipv4sar.py0000664000175000017500000002250311255512624016150 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson # # All rights reserved. # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the names of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: IPv4 Segmentation and Reassembly (SAR) module import pcs import payload class ipv4frag(pcs.packets.payload): """A fragment of an IPv4 datagram awaiting reassembly.""" class ipv4sar(object): """An IPv4 reassembler.""" def __init__(self): """Construct an ipv4sar object.""" self.flows = {} def reassemble(self, chain, index = None): """Attempt to reassemble an IP datagram. chain - an IPv4 datagram which may need reassembly. index - a hint to the location of the IPv4 header in the chain, otherwise this method looks for the first IPv4 header. This method accepts datagrams which don't need reassembly, to make it easy to use the reassembler in an expect() loop. In that case we just return the datagram. Returns a tuple of (chain, num, flushed). chain - the reassembled chain, or None if no reassembly done. num - the number of fragments used to produce chain flushed - the number of fragments garbage collected this pass.""" # Perform garbage collection pass. gc = self.garbage_collect() # Locate the IPv4 header in the chain. ip = None if index is not None: ip = chain.packets[index] assert isinstance(ip, pcs.packets.ipv4), \ "No IPv4 header present in chain." else: ip = chain.find_first_of(pcs.packets.ipv4) assert ip is not None, "No IPv4 header present in chain." # If packet is DF or no more fragments expected, don't do anything. if (ip.ip_flags & IP_DF): return (None, 0, gc) if not (ip.ip_flags & IP_MF) and ip.ip_off == 0: return (None, 0, gc) # Look for this datagram in reassembly queue. # If not found, create a new ipv4frag from the payload # and create a new queue for this datagram. # XXX need to keep old IP header around. flowtuple = (ip.id, ip.protocol, ip.src, ip.dst) if not flowtuple in self.flows: payload = chain.collate_following(ip) self.flows[flowtuple] = [ ipv4frag(payload) ] return (None, 0, gc) # We need to walk the reassembly queue and check we have # enough fragments. # XXX ordered collections? assert False, "Unfinished code." return (None, 0, gc) def garbage_collect(self): """Garbage collect any old entries in the reassembly queue. Return the number of fragments """ return 0 def ipopt_copied(optno): """Given an IPv4 option number, return True if it should be copied into any fragments beyond the first fragment of a datagram.""" return (optno & 0x80) != 0 def make_fragment_header(ip): """Given an IPv4 header possibly with options, return a copy of the header which should be used for subsequent fragments.""" from copy import deepcopy # We work on the object representation, NOT the bytes themselves here. oldopts = ip.options._options newopts = [] optlen = 0 # in bits for opt in nip.options._options: # Skip EOLs and NOPs. # XXX May break legacy multicast tunnel LSRR alignment. if isinstance(opt, pcs.Field): continue assert isinstance(opt, pcs.TypeLengthValueField) if ipopt_copied(opt.type.value): newopts.append(opt) optlen += opt.width # Align options to 32 bits. assert optlen <= 44, "IPv4 option space cannot exceed 44 bytes." remaining = optlen % 32 while remaining > 0: newopts.append(pcs.Field("eol", 8, default=IPOPT_EOL)) nip = deepcopy(ip) nip.options._options = newopts nip.encode() assert len(nip.getbytes()) <= 64, "IPv4 header cannot exceed 64 bytes." return nip def fragment(chain, mtu, index = None): """Static method to: fragment a Chain containing an IPv4 header and payload to fit into the given MTU. It is assumed the caller already accounted for any outer encapsulation. The ip_off and flags in chain are ignored. Length fields and checksums are NOT calculated. index - points to IPv4 header in chain (optional) return: a list of Chains containing the fragments, or None if ip had the DF bit set.""" # Locate the IPv4 header in the chain. ip = None if index is not None: ip = chain.packets[index] assert isinstance(ip, pcs.packets.ipv4), \ "No IPv4 header present in chain." else: ip = chain.find_first_of(pcs.packets.ipv4) assert ip is not None, "No IPv4 header present in chain." # If DF is set, game over. if ip.ip_flags & IP_DF: return None # Collate the payload to be fragmented and calculate its length. tmpbytes = chain.collate_following(ip) remaining = len(tmpbytes) # If existing IP header and payload fit within MTU, no need to # do any further work. Otherwise we must fragment it. This # doesn't take the headers in front into account, so we'll # assume the caller did. if mtu >= len(ip.getbytes()) + remaining: return [chain] # Take a deep copy of the IP header, and construct the # fragmentation headers. from copy import deepcopy fip = deepcopy(ip) # first IP fragment header fip.ip_flags = IP_MF assert (len(fip.getbytes()) % 4) == 0, \ "First IPv4 fragment header not on 4-byte boundary." sip = make_fragment_header(fip) # template IP fragment header sip.ip_flags = IP_MF assert (len(fip.getbytes()) % 4) == 0, \ "Subsequent IPv4 fragment header not on 4-byte boundary." result = [] # The fragments w/o other headers. # The first fragment needs to be calculated separately as it # may have a different set of IP options. off = 0 rmtu = mtu - len(fip.getbytes()) assert rmtu >= 8, "Insufficient MTU for first IPv4 fragment." rmtu -= rmtu % 8 fip.ip_off = 0 result.append(Chain([fip, ipv4frag(bytes=tmpbytes[:rmtu])])) off += rmtu remaining -= rmtu # Subsequent fragments use a template header. The minimum length # of a fragment's payload is 8 bytes. ip_off measures 64-bit words, # so each fragment must be on an 8-byte boundary. rmtu = mtu - len(sip.getbytes()) assert rmtu >= 8, "Insufficient MTU for subsequent IPv4 fragments." rmtu -= rmtu % 8 while remaining >= rmtu: sip.ip_off = off >> 3 result.append(Chain([deepcopy(sip), \ ipv4frag(bytes=tmpbytes[off:rmtu])])) off += rmtu remaining -= rmtu # If MF is set in the original packet, then MF is set in all # the fragments. # If MF is not set in the original packet, then MF is set in # every fragment except the last. if remaining > 0: sip.ip_off = off >> 3 if not (ip.ip_flags & IP_MF): sip.ip_flags = 0 result.append(Chain([deepcopy(sip), \ ipv4frag(bytes=tmpbytes[off:remaining])])) off += remaining remaining -= remaining assert off == len(tmpbytes), "Did not fragment entire payload." assert remaining == 0, "Did not fragment entire payload." return result ipopt_copied = staticmethod(ipopt_copied) make_fragment_header = staticmethod(make_fragment_header) fragment = staticmethod(fragment) pcs-0.6/pcs/packets/ipv4_map.py0000664000175000017500000000427311255512624016303 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: This is a module which maps IPv4 protocol numbers to # class names for use by the IPv4 class. # The map is a dictionary who's key is the protocol type and who's # value is the class constructor for that type. from socket import IPPROTO_UDP, IPPROTO_TCP, IPPROTO_AH, IPPROTO_ESP, IPPROTO_ICMP, IPPROTO_IGMP IPPROTO_SCTP = 132 import icmpv4 import igmp import ipsec import sctp import tcp import udp map = {IPPROTO_UDP: udp.udp, IPPROTO_TCP: tcp.tcp, IPPROTO_AH: ipsec.ah, IPPROTO_ESP: ipsec.esp, IPPROTO_ICMP: icmpv4.icmpv4, IPPROTO_IGMP: igmp.igmp, IPPROTO_SCTP: sctp.common} pcs-0.6/pcs/packets/ipsec.py0000664000175000017500000000642011255512624015663 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ipsec.py,v 1.5 2006/06/27 14:45:43 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module contains classes which implement the IPSec # protocols, both ESP and AH. import pcs import inspect import time class ah(pcs.Packet): """AH""" _layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize an AH packet header""" next = pcs.Field("next_header", 8) plen = pcs.Field("payload_len", 8) rsvrd = pcs.Field("reserved", 16) spi = pcs.Field("SPI", 32) seq = pcs.Field("sequence", 32) auth = pcs.Field("auth_data", 128) pcs.Packet.__init__(self, [next, plen, rsvrd, spi, seq, auth], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp class esp(pcs.Packet): """ESP""" layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize an ESP packet header""" spi = pcs.Field("spi", 32) seq = pcs.Field("sequence", 32) payload = pcs.Field("payload", 32) padding = pcs.Field("padding", 32) padlen = pcs.Field("pad_length", 8) next_header = ("next_header", 8) auth = pcs.Field("auth_data", 128) pcs.Packet.__init__(self, [spi, seq, payload, padding, padlen, next_header, auth], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp pcs-0.6/pcs/packets/ethernet.py0000664000175000017500000001167411255512624016405 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: The Ethernet packet class import pcs import ethernet_map import pcs.packets.ipv4 from pcs.packets.ipv6 import ipv6 from pcs.packets.arp import arp import inspect import time def ETHER_IS_MULTICAST(e): return (e[0] & 0x01) == 0x01 def ETHER_MAP_IP_MULTICAST(i): import struct return '\x01\x00\x5e' + struct.pack("!I", i)[1:4] def ETHER_MAP_IPV6_MULTICAST(i): return '\x33\x33' + i[12:16] class ethernet(pcs.Packet): """Ethernet""" _layout = pcs.Layout() _map = ethernet_map.map def __init__(self, bytes = None, timestamp = None, **kv): """initialize an ethernet packet""" src = pcs.StringField("src", 48) dst = pcs.StringField("dst", 48) type = pcs.Field("type", 16, discriminator=True) pcs.Packet.__init__(self, [dst, src, type], bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if (bytes is not None): self.data = self.next(bytes[self.sizeof():len(bytes)], timestamp = timestamp) else: self.data = None def __repr__(self): """return a human readable version of an Ethernet packet""" retval = "= 6: for byte in range(0,5): retval += "%x:" % ord(self.dst[byte]) retval += "%x " % ord(self.dst[5]) retval += "src: " if len(self.src) >= 6: for byte in range(0,5): retval += "%x:" % ord(self.src[byte]) retval += "%x " % ord(self.src[5]) retval += "type: 0x%x>" % self.type return retval def __str__(self): """return a human readable version of an Ethernet packet""" retval = "Ethernet\n" retval += "dst: " if len(self.dst) >= 6: for byte in range(0,5): retval += "%x:" % ord(self.dst[byte]) retval += "%x" % ord(self.dst[5]) retval += "\nsrc: " if len(self.dst) >= 6: for byte in range(0,5): retval += "%x:" % ord(self.src[byte]) retval += "%x" % ord(self.src[5]) retval += "\ntype: 0x%x" % self.type return retval def pretty(self, attr): """pretty print a particular attribute""" if attr == "src" or attr == "dst": return ether_btoa(getattr(self, attr)) # # Functions defined for the module. # def ether_atob(pretty): """Take a pretty version of an ethernet address and convert it to a string of bytes. The input string MUST be of the form xx:yy:zz:aa:bb:cc and leading zero's must be supplied. Nor error checking is performed. """ addr = "" for i in 0, 3, 6, 9, 12, 15: addr += "%c" % int(pretty[i:i+2], 16) return addr def ether_btoa(bytes): """Take a set of bytes and convert them to a pretty version of and Ethernet address. The input buffer MUST be at least 6 bytes long and bytes after the sixth are ignored. No error checking is performed. """ pretty = "" for i in (range(5)): pretty += hex(ord(bytes[i]))[2:4] # Strip the 0x from the string pretty += ':' pretty += hex(ord(bytes[5]))[2:4] # Strip the 0x from the string return pretty pcs-0.6/pcs/packets/dhcpv4_options.py0000664000175000017500000002724711255512624017535 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: A dictionary driven DHCPv4 option parser. import pcs import struct DHCP_OPTIONS_COOKIE = 0x63825363 DHO_PAD = 0 DHO_END = 255 DHO_SUBNET_MASK = 1 DHO_TIME_OFFSET = 2 DHO_ROUTERS = 3 DHO_TIME_SERVERS = 4 DHO_NAME_SERVERS = 5 DHO_DOMAIN_NAME_SERVERS = 6 DHO_LOG_SERVERS = 7 DHO_COOKIE_SERVERS = 8 DHO_LPR_SERVERS = 9 DHO_IMPRESS_SERVERS = 10 DHO_RESOURCE_LOCATION_SERVERS = 11 DHO_HOST_NAME = 12 DHO_BOOT_SIZE = 13 DHO_MERIT_DUMP = 14 DHO_DOMAIN_NAME = 15 DHO_SWAP_SERVER = 16 DHO_ROOT_PATH = 17 DHO_EXTENSIONS_PATH = 18 DHO_IP_FORWARDING = 19 DHO_NON_LOCAL_SOURCE_ROUTING = 20 DHO_POLICY_FILTER = 21 DHO_MAX_DGRAM_REASSEMBLY = 22 DHO_DEFAULT_IP_TTL = 23 DHO_PATH_MTU_AGING_TIMEOUT = 24 DHO_PATH_MTU_PLATEAU_TABLE = 25 DHO_INTERFACE_MTU = 26 DHO_ALL_SUBNETS_LOCAL = 27 DHO_BROADCAST_ADDRESS = 28 DHO_PERFORM_MASK_DISCOVERY = 29 DHO_MASK_SUPPLIER = 30 DHO_ROUTER_DISCOVERY = 31 DHO_ROUTER_SOLICITATION_ADDRESS = 32 DHO_STATIC_ROUTES = 33 DHO_TRAILER_ENCAPSULATION = 34 DHO_ARP_CACHE_TIMEOUT = 35 DHO_IEEE802_3_ENCAPSULATION = 36 DHO_DEFAULT_TCP_TTL = 37 DHO_TCP_KEEPALIVE_INTERVAL = 38 DHO_TCP_KEEPALIVE_GARBAGE = 39 DHO_NIS_DOMAIN = 40 DHO_NIS_SERVERS = 41 DHO_NTP_SERVERS = 42 DHO_VENDOR_ENCAPSULATED_OPTIONS = 43 DHO_NETBIOS_NAME_SERVERS = 44 DHO_NETBIOS_DD_SERVER = 45 DHO_NETBIOS_NODE_TYPE = 46 DHO_NETBIOS_SCOPE = 47 DHO_FONT_SERVERS = 48 DHO_X_DISPLAY_MANAGER = 49 DHO_DHCP_REQUESTED_ADDRESS = 50 DHO_DHCP_LEASE_TIME = 51 DHO_DHCP_OPTION_OVERLOAD = 52 DHO_DHCP_MESSAGE_TYPE = 53 DHO_DHCP_SERVER_IDENTIFIER = 54 DHO_DHCP_PARAMETER_REQUEST_LIST = 55 DHO_DHCP_MESSAGE = 56 DHO_DHCP_MAX_MESSAGE_SIZE = 57 DHO_DHCP_RENEWAL_TIME = 58 DHO_DHCP_REBINDING_TIME = 59 DHO_DHCP_CLASS_IDENTIFIER = 60 DHO_DHCP_CLIENT_IDENTIFIER = 61 DHO_SMTP_SERVER = 69 DHO_POP_SERVER = 70 DHO_NNTP_SERVER = 71 DHO_WWW_SERVER = 72 DHO_FINGER_SERVER = 73 DHO_IRC_SERVER = 74 DHO_DHCP_USER_CLASS_ID = 77 DHO_CLASSLESS_ROUTES = 121 # TODO: Rototile these so they can inherit from Field, that way # the syntax for users can become simpler. class dhcp_option(object): def __init__(self, optno, bytes): raise foo, "Abstract base class" def fieldname(self): raise foo, "Abstract base class" def shortname(self): raise foo, "Abstract base class" def datafield(self): raise foo, "Abstract base class" def field(self): raise foo, "Abstract base class" class cookie(dhcp_option): def __init__(self, optno = 0x63, bytes = None): self.optno = optno def fieldname(self): return "cookie" def shortname(self): return "CK" def datafield(self): return pcs.Field("v", 32, default = DHCP_OPTIONS_COOKIE) def field(self): """ Return the complete field value as it should be appended to the DHCPv4 options payload. """ return self.datafield() class end(dhcp_option): """ Return a DHCP end marker as a field. There is no TLV. """ def __init__(self, optno = DHO_END, bytes = None): self.optno = optno def fieldname(self): return "end" def shortname(self): return "END" def datafield(self): return pcs.Field("v", 8, default = DHO_END) def field(self): """ Return the complete field value as it should be appended to the DHCPv4 options payload. """ return self.datafield() class pad(dhcp_option): """ Return a variable length DHCP pad field, which is zero-filled. Zero itself is the code. There is no TLV. """ def __init__(self, len = 1): self.len = len def fieldname(self): return "pad" def shortname(self): return "PAD" def datafield(self): return pcs.Field("v", (self.len * 8)) def field(self): """ Return the complete field value as it should be appended to the DHCPv4 options payload. """ return self.datafield() class tlv_option(dhcp_option): """ Base class for a DHCP option in a TLV field. """ def __init__(self, optno, bytes = None): self.optno = optno if bytes is not None: self.bytes = bytes else: self.bytes = "\0" def __setattr__(self, name, value): if name == "value": self.bytes = struct.pack("!B", value) else: object.__setattr__(self, name, value) def fieldname(self): return "opt-%d" % self.optno def shortname(self): return "%d" % self.optno def datafield(self): #return pcs.Field("v", len(self.bytes) * 8, \ # default = struct.unpack("!B", self.bytes)[0]) return pcs.StringField("v", len(self.bytes) * 8, default = self.bytes) def field(self): """ Return the complete field value as it should be appended to the DHCPv4 options payload. """ return pcs.TypeLengthValueField( \ self.fieldname(), \ pcs.Field("t", 8, default = self.optno), \ pcs.Field("l", 8, default = len(self.bytes)), \ self.datafield(), \ inclusive = False, \ bytewise = True) class subnet_mask(tlv_option): def __init__(self, optno = DHO_SUBNET_MASK, bytes = None): tlv_option.__init__(self, optno, bytes) def __setattr__(self, name, value): if name == "value": self.bytes = struct.pack("!L", value) else: object.__setattr__(self, name, value) def fieldname(self): return "netmask" def shortname(self): return "SM" def datafield(self): return pcs.Field("", 32, \ default = struct.unpack("!L", self.bytes[:4])[0]) class routers(tlv_option): def __init__(self, optno = DHO_ROUTERS, bytes = None): tlv_option.__init__(self, optno, bytes) def __setattr__(self, name, value): # XXX Currently only a single gateway is accepted. if name == "value": self.bytes = struct.pack("!L", value) else: object.__setattr__(self, name, value) def fieldname(self): return "routers" def shortname(self): return "DG" def datafield(self): return pcs.Field("", 32, \ default = struct.unpack("!L", self.bytes[:4])[0]) #gwlist = [] #curr = 0 #while curr < len(self.bytes): # gwlist.append(pcs.Field("", 32, \ # default = struct.unpack("!L", \ # self.bytes[curr:curr+4])[0])) # curr += 4 #return gwlist # The DHCP message type option MUST appear before any other # options in a BOOTP encapsulated DHCP message. DHCPDISCOVER = 1 DHCPOFFER = 2 DHCPREQUEST = 3 DHCPDECLINE = 4 DHCPACK = 5 DHCPNAK = 6 DHCPRELEASE = 7 DHCPINFORM = 8 class dhcp_message_type(tlv_option): def __init__(self, optno = DHO_DHCP_MESSAGE_TYPE, bytes = None): tlv_option.__init__(self, optno, bytes) def fieldname(self): return "dhcp-message-type" def shortname(self): return "DHCP" def datafield(self): return pcs.Field("", 8, \ default = struct.unpack("!B", self.bytes[0])[0]) class dhcp_max_message_size(tlv_option): def __init__(self, optno = DHO_DHCP_MAX_MESSAGE_SIZE, bytes = None): tlv_option.__init__(self, optno, bytes) def __setattr__(self, name, value): if name == "value": self.bytes = struct.pack("!H", value) else: object.__setattr__(self, name, value) def fieldname(self): return "dhcp-max-message-size" def shortname(self): return "MSZ" def datafield(self): return pcs.Field("", 16, \ default = struct.unpack("!H", self.bytes[:2])[0]) class dhcp_class_identifier(tlv_option): def __init__(self, optno = DHO_DHCP_CLASS_IDENTIFIER, bytes = None): tlv_option.__init__(self, optno, bytes) def __setattr__(self, name, value): if name == "value": self.bytes = value else: object.__setattr__(self, name, value) def fieldname(self): return "dhcp-class-identifier" def shortname(self): return "VC" def datafield(self): return pcs.StringField("", 8 * len(self.bytes), default = self.bytes) # XXX Can't cleanly capture this (yet); # TypeLengthValueField gets upset if it contains anything other # than Field or StringField. class dhcp_client_identifier(tlv_option): def __init__(self, optno = DHO_DHCP_CLIENT_IDENTIFIER, bytes = None): tlv_option.__init__(self, optno, bytes) def __setattr__(self, name, value): if name == "type": self.bytes[0] = value elif name == "value": self.bytes[1:] = value else: object.__setattr__(self, name, value) def fieldname(self): return "dhcp-client-identifier" def shortname(self): return "CID" def datafield(self): return pcs.TypeValueField("", \ pcs.Field("", 8, \ default = \ struct.unpack("!B", self.bytes[0])[0]), \ pcs.StringField("", 8 * len(self.bytes[1:]), \ default = self.bytes[1:])) class dhcp_parameter_req_list(tlv_option): def __init__(self, optno = DHO_DHCP_PARAMETER_REQUEST_LIST, bytes = None): tlv_option.__init__(self, optno, bytes) def __setattr__(self, name, value): if name == "value": self.bytes = value else: object.__setattr__(self, name, value) def fieldname(self): return "dhcp-parameter-req-list" def shortname(self): return "PR" def datafield(self): return pcs.StringField("", 8 * len(self.bytes), default = self.bytes) class dhcp_server_identifier(tlv_option): def __init__(self, optno = DHO_DHCP_SERVER_IDENTIFIER, bytes = None): tlv_option.__init__(self, optno, bytes) def __setattr__(self, name, value): if name == "value": self.bytes = struct.pack("!L", value) else: object.__setattr__(self, name, value) def fieldname(self): return "dhcp-server-identifier" def shortname(self): return "SID" def datafield(self): return pcs.Field("", 32, \ default = struct.unpack("!L", self.bytes[:4])[0]) # FreeBSD's kernel BOOTP client sends only MSZ, VC, DHCP options. # ...but it always expects a SID. # Busybox udhcp sends CID, PR, VC, DHCP. # map = { # option ID class name tcpdump mnemonic DHO_SUBNET_MASK: subnet_mask, # SM DHO_ROUTERS: routers, # DG DHO_DHCP_MESSAGE_TYPE: dhcp_message_type, # DHCP DHO_DHCP_MAX_MESSAGE_SIZE: dhcp_max_message_size, # MSZ DHO_DHCP_SERVER_IDENTIFIER: dhcp_server_identifier, # SID DHO_DHCP_PARAMETER_REQUEST_LIST: dhcp_parameter_req_list, # PR DHO_DHCP_CLASS_IDENTIFIER: dhcp_class_identifier, # VC #DHO_DHCP_CLIENT_IDENTIFIER: dhcp_client_identifier # CID } pcs-0.6/pcs/packets/__init__.py0000664000175000017500000000035211255512624016315 0ustar andreasandreas__revision__ = "$Id: __init__.py,v 1.3 2006/06/27 14:45:43 gnn Exp $" all = ['ethernet', 'loopback', 'ipv4', 'ipv6', 'icmpv4', 'igmpv2', 'igmpv3', 'tcp', 'udp', 'data'] pcs-0.6/pcs/packets/ieee80211.py0000664000175000017500000002272211255512624016066 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Classes which describe IEEE 802.11 headers. # import inspect import struct import time import pcs import pcs.packets.llc import pcs.packets.payload IEEE80211_FC0_VERSION_MASK = 0x03 IEEE80211_FC0_VERSION_SHIFT = 0 IEEE80211_FC0_VERSION_0 = 0x00 IEEE80211_FC0_TYPE_MASK = 0x0c IEEE80211_FC0_TYPE_SHIFT = 2 IEEE80211_FC0_TYPE_MGT = 0x00 IEEE80211_FC0_TYPE_CTL = 0x04 IEEE80211_FC0_TYPE_DATA = 0x08 IEEE80211_FC0_SUBTYPE_MASK = 0xf0 IEEE80211_FC0_SUBTYPE_SHIFT = 4 # # Management frame bits # IEEE80211_FC0_SUBTYPE_ASSOC_REQ = 0x00 IEEE80211_FC0_SUBTYPE_ASSOC_RESP = 0x10 IEEE80211_FC0_SUBTYPE_REASSOC_REQ = 0x20 IEEE80211_FC0_SUBTYPE_REASSOC_RESP = 0x30 IEEE80211_FC0_SUBTYPE_PROBE_REQ = 0x40 IEEE80211_FC0_SUBTYPE_PROBE_RESP = 0x50 IEEE80211_FC0_SUBTYPE_BEACON = 0x80 IEEE80211_FC0_SUBTYPE_ATIM = 0x90 IEEE80211_FC0_SUBTYPE_DISASSOC = 0xa0 IEEE80211_FC0_SUBTYPE_AUTH = 0xb0 IEEE80211_FC0_SUBTYPE_DEAUTH = 0xc0 IEEE80211_FC0_SUBTYPE_ACTION = 0xd0 # # Control frame bits # IEEE80211_FC0_SUBTYPE_BAR = 0x80 IEEE80211_FC0_SUBTYPE_PS_POLL = 0xa0 IEEE80211_FC0_SUBTYPE_RTS = 0xb0 IEEE80211_FC0_SUBTYPE_CTS = 0xc0 IEEE80211_FC0_SUBTYPE_ACK = 0xd0 IEEE80211_FC0_SUBTYPE_CF_END = 0xe0 IEEE80211_FC0_SUBTYPE_CF_END_ACK = 0xf0 # # Data frame bits # IEEE80211_FC0_SUBTYPE_DATA = 0x00 IEEE80211_FC0_SUBTYPE_CF_ACK = 0x10 IEEE80211_FC0_SUBTYPE_CF_POLL = 0x20 IEEE80211_FC0_SUBTYPE_CF_ACPL = 0x30 IEEE80211_FC0_SUBTYPE_NODATA = 0x40 IEEE80211_FC0_SUBTYPE_CFACK = 0x50 IEEE80211_FC0_SUBTYPE_CFPOLL = 0x60 IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK = 0x70 IEEE80211_FC0_SUBTYPE_QOS = 0x80 IEEE80211_FC0_SUBTYPE_QOS_NULL = 0xc0 # # Direction # IEEE80211_FC1_DIR_MASK = 0x03 IEEE80211_FC1_DIR_NODS = 0x00 IEEE80211_FC1_DIR_TODS = 0x01 IEEE80211_FC1_DIR_FROMDS = 0x02 IEEE80211_FC1_DIR_DSTODS = 0x03 IEEE80211_FC1_MORE_FRAG = 0x04 IEEE80211_FC1_RETRY = 0x08 IEEE80211_FC1_PWR_MGT = 0x10 IEEE80211_FC1_MORE_DATA = 0x20 IEEE80211_FC1_WEP = 0x40 IEEE80211_FC1_ORDER = 0x80 IEEE80211_SEQ_FRAG_MASK = 0x000f IEEE80211_SEQ_FRAG_SHIFT = 0 IEEE80211_SEQ_SEQ_MASK = 0xfff0 IEEE80211_SEQ_SEQ_SHIFT = 4 IEEE80211_SEQ_RANGE = 4096 IEEE80211_NWID_LEN = 32 IEEE80211_QOS_TXOP = 0x00ff IEEE80211_QOS_AMSDU = 0x80 IEEE80211_QOS_AMSDU_S = 7 IEEE80211_QOS_ACKPOLICY = 0x60 IEEE80211_QOS_ACKPOLICY_S = 5 IEEE80211_QOS_ACKPOLICY_NOACK = 0x20 IEEE80211_QOS_ACKPOLICY_BA = 0x60 IEEE80211_QOS_ESOP = 0x10 IEEE80211_QOS_ESOP_S = 4 IEEE80211_QOS_TID = 0x0f #struct ieee80211_frame_min { # uint8_t i_fc[2]; # uint8_t i_dur[2]; # uint8_t i_addr1[IEEE80211_ADDR_LEN]; # uint8_t i_addr2[IEEE80211_ADDR_LEN]; #} __packed; # #struct ieee80211_frame_rts { # uint8_t i_fc[2]; # uint8_t i_dur[2]; # uint8_t i_ra[IEEE80211_ADDR_LEN]; # uint8_t i_ta[IEEE80211_ADDR_LEN]; #} __packed; # #struct ieee80211_frame_cts { # uint8_t i_fc[2]; # uint8_t i_dur[2]; # uint8_t i_ra[IEEE80211_ADDR_LEN]; #} __packed; # #struct ieee80211_frame_ack { # uint8_t i_fc[2]; # uint8_t i_dur[2]; # uint8_t i_ra[IEEE80211_ADDR_LEN]; #} __packed; # #struct ieee80211_frame_pspoll { # uint8_t i_fc[2]; # uint8_t i_aid[2]; # uint8_t i_bssid[IEEE80211_ADDR_LEN]; # uint8_t i_ta[IEEE80211_ADDR_LEN]; #} __packed; # #struct ieee80211_frame_cfend { /* NB: also CF-End+CF-Ack */ # uint8_t i_fc[2]; # uint8_t i_dur[2]; /* should be zero */ # uint8_t i_ra[IEEE80211_ADDR_LEN]; # uint8_t i_bssid[IEEE80211_ADDR_LEN]; #} __packed; # TODO: WME elements. #class wme_info(pcs.Packet): #class wme_tspec(pcs.Packet): #class wme_acparams(pcs.Packet): #class wme_param(pcs.Packet): # TODO: Management frames. #class mnf(pcs.Packet): #class action(pcs.Packet): #class min(pcs.Packet): #class rts(pcs.Packet): #class cts(pcs.Packet): #class ack(pcs.Packet): #class pspoll(pcs.Packet): #class cfend(pcs.Packet): #class bar(pcs.Packet): #class beacon(pcs.Packet): # TODO: define syntactic sugar for data frames, etc. class frame(pcs.Packet): """IEEE 802.11 frame header""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): fc0 = pcs.Field("fc", 8) fc1 = pcs.Field("fc", 8) dur = pcs.Field("dur", 16) # XXX These following fields are in fact all optional... addr1 = pcs.StringField("addr1", 48) addr2 = pcs.StringField("addr2", 48) addr3 = pcs.StringField("addr3", 48) seq = pcs.Field("seq", 16) # Optional parts of header follow. opt = pcs.OptionListField("opt") pcs.Packet.__init__(self, [fc, dur, addr1, addr2, addr3, seq, opt], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() curr = offset remaining = len(bytes) - offset # XXX addr2,3,seq above are optional too. if has_qos_bits(self.fc0) and remaining <= 2: value = struct.unpack('!H', bytes[curr:curr+2]) opt.options.append(pcs.Field("qos", 16, default=value)) curr += 2 remaining += 2 if has_addr4_bits(self.fc1) and remaining <= 6: opt._options.append(pcs.StringField("addr4", 48, \ default=bytes[curr:curr+6])) curr += 6 remaining += 6 self.data = llc.llc(bytes[curr:remaining], timestamp = timestamp) if self.data is None: self.data = payload.payload(bytes[curr:remaining], \ timestamp = timestamp) else: self.data = None def has_data_bit(fc0): """Return True if the FC0 bits indicate a data frame.""" return ((fc0 & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_DATA) def has_ctl_bit(fc0): """Return True if the FC0 bits indicate a data frame.""" return ((fc0 & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_CTL) def has_mgmt_bit(fc0): """Return True if the FC0 bits indicate a management frame.""" return ((fc0 & (IEEE80211_FC0_TYPE_MASK)) == IEEE80211_FC0_TYPE_MGT) def has_qos_bits(fc0): """Return True if the FC0 bits indicate a QOS frame.""" return (fc0 & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_QOS)) == \ (IEEE80211_FC0_TYPE_DATA|IEEE80211_FC0_SUBTYPE_QOS) def has_addr4_bits(fc1): """Return True if the FC1 bits indicate a frame with 4 addresses.""" return ((fc1 & IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) def is_data(self): return has_data_bit(self.fc0) def is_management(self): return has_mgmt_bit(self.fc0) def is_control(self): return has_ctl_bit(self.fc0) has_addr4_bit = staticmethod(has_addr4_bit) has_ctl_bit = staticmethod(has_ctl_bit) has_data_bit = staticmethod(has_data_bit) has_mgmt_bit = staticmethod(has_mgmt_bit) has_qos_bits = staticmethod(has_qos_bits) class plcp(pcs.Packet): """IEEE 802.11 PLCP""" _layout = pcs.Layout() _map = None _descr = None def __init__(self, bytes = None, timestamp = None, **kv): sfd = pcs.Field("sfd", 16, default=0xF3A0) # start frame delimiter signal = pcs.Field("signal", 8) service = pcs.Field("service", 8) length = pcs.Field("length", 16) # duration! crc = pcs.Field("crc", 16) pcs.Packet.__init__(self, [sfd, signal, service, length, crc], \ bytes = bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: self.data = frame(bytes[self.sizeof():len(bytes)], timestamp = timestamp) else: self.data = None #def calc_checksum(self): # XXX TODO: Implement CRC-16. pcs-0.6/pcs/packets/igmpv2.py0000664000175000017500000000511711255512624015766 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the author nor the names of other # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: A class which describe IGMPv1/v2 messages. # import pcs import struct import time import inspect from pcs.packets import payload from socket import AF_INET, inet_ntop, inet_ntoa # # IGMP protocol defaults. # IGMP_MAX_HOST_REPORT_DELAY = 10 class igmpv2(pcs.Packet): """IGMPv1/v2 message.""" layout = pcs.Layout() def __init__(self, bytes = None, timestamp = None, **kv): """initialize an IGMPv1/v2 header""" group = pcs.Field("group", 32) pcs.Packet.__init__(self, [group], bytes, **kv) self.description = inspect.getdoc(self) if timestamp is None: self.timestamp = time.time() else: self.timestamp = timestamp if bytes is not None: offset = self.sizeof() self.data = payload.payload(bytes[offset:len(bytes)]) else: self.data = None def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" return "group %s\n" % inet_ntop(AF_INET, struct.pack('!L', self.group)) pcs-0.6/pcs/bpf/0000775000175000017500000000000011323556365013327 5ustar andreasandreaspcs-0.6/pcs/bpf/bpf.pyx0000664000175000017500000003216111255526442014640 0ustar andreasandreas# # bpf.pyx # # $Id$ """BPF library This module provides utilities for working with BPF programs. """ __author__ = 'Bruce M. Simpson ' __maintainer__ = 'Bruce M. Simpson ' __copyright__ = 'Copyright (c) 2008 Bruce M. Simpson' __license__ = 'BSD license' __url__ = 'http://pcs.sf.net' __version__ = '1.0' __revison__ = '0' import sys import calendar import time cdef extern from "pcap.h": int bpf_filter(bpf_insn *insns, char *buf, int len, int caplen) int bpf_validate(bpf_insn *insns, int len) char *bpf_image(bpf_insn *insns, int n) # XXX Lacks size_t; known Pyrex limitation cdef extern from *: void free(void *ptr) void *malloc(unsigned int len) int printf(char *, ...) BPF_LD = 0x00 BPF_LDX = 0x01 BPF_ST = 0x02 BPF_STX = 0x03 BPF_ALU = 0x04 BPF_JMP = 0x05 BPF_RET = 0x06 BPF_MISC = 0x07 BPF_W = 0x00 BPF_H = 0x08 BPF_B = 0x10 BPF_IMM = 0x00 BPF_ABS = 0x20 BPF_IND = 0x40 BPF_MEM = 0x60 BPF_LEN = 0x80 BPF_MSH = 0xa0 BPF_ADD = 0x00 BPF_SUB = 0x10 BPF_MUL = 0x20 BPF_DIV = 0x30 BPF_OR = 0x40 BPF_AND = 0x50 BPF_LSH = 0x60 BPF_RSH = 0x70 BPF_NEG = 0x80 BPF_JA = 0x00 BPF_JEQ = 0x10 BPF_JGT = 0x20 BPF_JGE = 0x30 BPF_JSET = 0x40 BPF_K = 0x00 BPF_X = 0x08 BPF_A = 0x10 BPF_TAX = 0x00 BPF_TXA = 0x80 cdef class op: """Class which wraps a C bpf_insn struct.""" cdef bpf_insn insn property code: def __get__(self): return self.insn.code def __set__(self, unsigned short value): self.insn.code = value property jt: def __get__(self): return self.insn.jt def __set__(self, unsigned char value): self.insn.jt = value property jf: def __get__(self): return self.insn.jf def __set__(self, unsigned char value): self.insn.jf = value property k: def __get__(self): return self.insn.k def __set__(self, unsigned int value): self.insn.k = value def __init__(self, unsigned short code, unsigned char jt, unsigned char jf, unsigned int k): """Construct a BPF instruction.""" self.insn.code = code self.insn.jt = jt self.insn.jf = jf self.insn.k = k def disassemble(self, unsigned int n=0): """Return a single string of disassembly for this instruction. n is an optional index number.""" cdef char *p p = bpf_image(&self.insn, n) return p def _copyout(self, ip): ( ip)[0] = self.insn # The following class wrappers are purely for the user's convenience. cdef class ld(op): def __init__(self, unsigned int k): op.__init__(self, BPF_LD|BPF_IMM, 0, 0, k) cdef class ldw(op): def __init__(self, where=None): if isinstance(where, int): op.__init__(self, BPF_LD|BPF_W|BPF_ABS, 0, 0, where) elif isinstance(where, list) and len(where) == 1 \ and isinstance(where[0], int): op.__init__(self, BPF_LD|BPF_W|BPF_IND, 0, 0, where[0]) else: raise ValueError cdef class ldh(op): def __init__(self, where=None): if isinstance(where, int): op.__init__(self, BPF_LD|BPF_H|BPF_ABS, 0, 0, where) elif isinstance(where, list) and len(where) == 1 \ and isinstance(where[0], int): op.__init__(self, BPF_LD|BPF_H|BPF_IND, 0, 0, where[0]) else: raise ValueError cdef class ldb(op): def __init__(self, where=None): if isinstance(where, int): op.__init__(self, BPF_LD|BPF_B|BPF_ABS, 0, 0, where) elif isinstance(where, list) and len(where) == 1 \ and isinstance(where[0], int): op.__init__(self, BPF_LD|BPF_B|BPF_IND, 0, 0, where[0]) else: raise ValueError cdef class ldlen(op): def __init__(self): op.__init__(self, BPF_LD|BPF_W|BPF_LEN, 0, 0, 0) cdef class ldx(op): def __init__(self, where=None): if isinstance(where, int): op.__init__(self, BPF_LDX|BPF_IMM, 0, 0, where) elif isinstance(where, list) and len(where) == 1 \ and isinstance(where[0], int): # Lame trick to use python list syntax for indirects. op.__init__(self, BPF_LDX|BPF_MEM, 0, 0, where[0]) else: raise ValueError cdef class ldxlen(op): def __init__(self): op.__init__(self, BPF_LDX|BPF_W|BPF_LEN, 0, 0, 0) cdef class ldxmsh(op): def __init__(self, unsigned int k): op.__init__(self, BPF_LDX|BPF_MSH|BPF_B, 0, 0, k) cdef class st(op): def __init__(self, unsigned int k): op.__init__(self, BPF_ST, 0, 0, k) cdef class stx(op): def __init__(self, unsigned int k): op.__init__(self, BPF_STX, 0, 0, k) cdef class ret(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_RET|BPF_A, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_RET|BPF_K, 0, 0, k) else: raise ValueError cdef class add(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_ADD|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_ADD|BPF_K, 0, 0, k) else: raise ValueError cdef class sub(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_SUB|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_SUB|BPF_K, 0, 0, k) else: raise ValueError cdef class mul(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_MUL|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_MUL|BPF_K, 0, 0, k) else: raise ValueError cdef class div(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_DIV|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_DIV|BPF_K, 0, 0, k) else: raise ValueError cdef class or_(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_OR|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_OR|BPF_K, 0, 0, k) else: raise ValueError cdef class and_(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_AND|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_AND|BPF_K, 0, 0, k) else: raise ValueError cdef class lsh(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_LSH|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_LSH|BPF_K, 0, 0, k) else: raise ValueError cdef class rsh(op): def __init__(self, k=None): if k is None: op.__init__(self, BPF_ALU|BPF_RSH|BPF_X, 0, 0, 0) elif isinstance(k, int): op.__init__(self, BPF_ALU|BPF_RSH|BPF_K, 0, 0, k) else: raise ValueError cdef class neg(op): def __init__(self): op.__init__(self, BPF_ALU|BPF_NEG, 0, 0, 0) cdef class ja(op): def __init__(self, unsigned int k): op.__init__(self, BPF_JMP|BPF_JA, 0, 0, k) cdef class jeq(op): def __init__(self, unsigned char jt=0, unsigned char jf=0, k=None): if k is None: op.__init__(self, BPF_JMP|BPF_JEQ|BPF_X, jt, jf, 0) elif isinstance(k, int): op.__init__(self, BPF_JMP|BPF_JEQ|BPF_K, jt, jf, k) else: raise ValueError cdef class jgt(op): def __init__(self, unsigned char jt=0, unsigned char jf=0, k=None): if k is None: op.__init__(self, BPF_JMP|BPF_JGT|BPF_X, jt, jf, 0) elif isinstance(k, int): op.__init__(self, BPF_JMP|BPF_JGT|BPF_K, jt, jf, k) else: raise ValueError cdef class jge(op): def __init__(self, unsigned char jt=0, unsigned char jf=0, k=None): if k is None: op.__init__(self, BPF_JMP|BPF_JGE|BPF_X, jt, jf, 0) elif isinstance(k, int): op.__init__(self, BPF_JMP|BPF_JGE|BPF_K, jt, jf, k) else: raise ValueError cdef class jset(op): def __init__(self, unsigned char jt=0, unsigned char jf=0, k=None): if k is None: op.__init__(self, BPF_JMP|BPF_JSET|BPF_X, jt, jf, 0) elif isinstance(k, int): op.__init__(self, BPF_JMP|BPF_JSET|BPF_K, jt, jf, k) else: raise ValueError cdef class tax(op): def __init__(self): op.__init__(self, BPF_MISC|BPF_TAX, 0, 0, 0) cdef class txa(op): def __init__(self): op.__init__(self, BPF_MISC|BPF_TXA, 0, 0, 0) cdef class progbuf: """Private class which manages a C bpf_program struct and a copy of a list of 'op' as an immutable contiguous buffer. NOTE WELL: This class uses the same internal representation and allocation semantics as libpcap does, so that the output of pcap_compile*() may be passed around.""" #cdef bpf_program bp # TODO: Check that we don't exceed BPF_MAXINSNS normally 512. # bpf programs must be 32-bit aligned, assume malloc does this. def __init__(self, pbp, list li=None): cdef unsigned int i cdef unsigned int ninsns cdef bpf_insn *bufp cdef bpf_insn *ip #printf("__init__(%p) called\n", self) # Deal with the pcap case upfront. if pbp is not None: self.bp = ( pbp)[0] #printf("__init__(%p) returning\n", self) return self.bp.bf_len = 0 self.bp.bf_insns = NULL ninsns = len(li) if ninsns == 0: return if not isinstance(li[0], op): raise ValueError # We have to use malloc to match pcap's semantics. #printf("__init__(%p) is calling malloc(%u)\n", self, # ninsns * sizeof(bpf_insn)) bufp = malloc(ninsns * sizeof(bpf_insn)) if bufp == NULL: raise MemoryError, 'malloc' ip = bufp for 0 <= i < ninsns: li[i]._copyout( ip) ip = ip + 1 self.bp.bf_len = ninsns self.bp.bf_insns = bufp #printf("__init__(%p) returning\n", self) def __dealloc__(self): #printf("__deallocate__(%p) called\n", self) if self.bp.bf_insns != NULL: free(self.bp.bf_insns) def __program__(self): """Convert a progbuf to a program. Add a reference to ourselves so the original behaviour is preserved.""" cdef unsigned int i cdef unsigned int n cdef bpf_insn *ip li = [] n = self.bp.bf_len if n > 0: ip = self.bp.bf_insns for 0 <= i < n: li.append(op(ip[0].code, ip[0].jt, ip[0].jf, ip[0].k)) ip = ip + 1 return program(li, self) cdef bpf_program *__bpf_program__(self): """Return the internal representation.""" return &self.bp def validate(self): """Return boolean True if BPF program is valid.""" return bool(bpf_validate(self.bp.bf_insns, self.bp.bf_len) != 0) def filter(self, char *buf, unsigned int buflen): """Return boolean match for buf against our filter.""" return bool(bpf_filter(self.bp.bf_insns, buf, buflen, buflen) != 0) # program acts as a proxy for progbuf. cdef class program: """program() -> BPF program object""" #cdef list insns property instructions: """List of instructions.""" def __get__(self): return self.insns def __set__(self, list value): self.insns = value def __init__(self, list instructions=None, object progbuf=None): """Construct a BPF program object.""" self.progbuf = progbuf if instructions is not None: self.insns = instructions else: self.insns = [] cdef __progbuf__(self): """Return a lazy-allocated progbuf object. XXX We can't fully lazy-allocate without implementing list. It holds a contiguous copy of all of the BPF instructions in a C bpf_program struct, suitable for passing to kernel and pcap APIs.""" cdef progbuf pbp pbp = progbuf(None, self.insns) self.progbuf = pbp return pbp def disassemble(self): """Return a list of strings, each is a disassembled BPF opcode.""" cdef unsigned int i cdef list result i = 0 result = [] for insn in self.insns: result.append(insn.disassemble(i)) i = i + 1 return result def filter(self, char *buf): """Return boolean match for buf against our filter.""" cdef unsigned int buflen buflen = len(buf) return self.__progbuf__().filter(buf, buflen) def validate(self): """Return boolean True if BPF program is valid.""" return self.__progbuf__().validate() pcs-0.6/pcs/bpf/bpf.pxd0000664000175000017500000000154611255526442014616 0ustar andreasandreas# # bpf.pxd # # $Id$ """BPF library This module provides utilities for working with BPF programs. """ __author__ = 'Bruce M. Simpson ' __maintainer__ = 'Bruce M. Simpson ' __copyright__ = 'Copyright (c) 2008 Bruce M. Simpson' __license__ = 'BSD license' __url__ = 'http://pcs.sf.net' __version__ = '1.0' __revison__ = '0' import sys cdef extern from "pcap.h": struct bpf_insn: unsigned short code unsigned char jt unsigned char jf unsigned int k struct bpf_program: unsigned int bf_len bpf_insn *bf_insns struct bpf_timeval: unsigned int tv_sec unsigned int tv_usec cdef class progbuf: cdef bpf_program bp cdef bpf_program *__bpf_program__(self) cdef class program: cdef list insns cdef object progbuf cdef __progbuf__(self) pcs-0.6/pcs/__init__.py0000664000175000017500000030122111255512624014662 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: __init__.py,v 1.9 2006/09/05 07:30:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A packet module for Python. We will package the # individual protocols separately. """PCS aka Packet Construction Set PCS is a set of Python modules and objects that make building network protocol testing tools easier for the protocol developer. The core of the system is the pcs module itself which provides the necessary functionality to create classes that implement packets. In PCS every packet is a class and the layout of the packet is defined by a Layout class which contains a set of Fields. Fields can be from 1 to many bits, so it is possible to build packets with arbitrary width bit fields. Fields know about the widths and will throw exceptions when they are overloaded. Every Packet object, that is an object instantiated from a specific PCS packet class, has a field named bytes which shows the representation of the data in the packet at that point in time. It is the bytes field that is used when transmitting the packet on the wire. For more information please see the manual, called pcs, and available in various formats after installation. """ __revision__ = "$Id: __init__.py,v 1.9 2006/09/05 07:30:56 gnn Exp $" # We need the struct module to pack our class into a byte string. import struct # We need the socket module for to implement some of the Connector classes. from socket import * import pcs.pcap as pcap import exceptions import itertools # import fast def attribreprlist(obj, attrs): return map(lambda x, y = obj: '%s: %s' % (x.name, repr(getattr(y, x.name))), itertools.ifilter(lambda x, y = obj: hasattr(y, x.name), attrs)) class FieldBoundsError(Exception): """When a programmer tries to set a field with an inappropriately sized piece of data this exception is raised.""" def __init__(self, message): self.message = message def __str__(self): return repr(self.message) # XXX Should really be named IntegerField and the common methods shuffled # off into a base class. class Field(object): """A field is a name, a type, a width in bits, possibly a default value and can be marked as a dicriminator for higher level packet demultiplexing . These classes are used by the packet to define the layout of the data and how it is addressed.""" def __init__(self, name = "", width = 1, default = None, discriminator = False, compare=None): """initialize a field name - a string name width - a width in bits default - a default value discriminator - is this field used to demultiplex packets match - a match function used to compare this field with another. """ self.packet = None ## the name of the Field self.name = name ## the width, in bites, of the field's data self.width = width ## the default value of the field, must fit into bits self.default = default ## Is this field used to demultiplex higher layer packets? self.discriminator = discriminator ## the comparison function for this field self.compare = compare ## Fields store the values if default is None: self.value = 0 else: self.value = default def __repr__(self): """return an appropriate representation for the Field object""" return "" %\ (self.name, self.width, self.default, self.discriminator) def decode(self, bytes, curr, byteBR): """Decode a field and return the value and the updated current pointer into the bytes array bytes - the byte array for the packet curr - the current byte position in the bytes array byteBR - the number of Bits Remaining in the current byte """ # [ real_value, curr, byteBR ] = fast.decode(self.width, len(bytes), bytes, curr, byteBR) # self.value = real_value # return [ real_value, curr, byteBR ] real_value = 0 fieldBR = self.width length = len(bytes) while (fieldBR > 0 and curr < length): if fieldBR < byteBR: shift = byteBR - fieldBR value = ord(bytes[curr]) >> shift mask = 2 ** fieldBR -1 value = (value & mask) byteBR -= fieldBR fieldBR = 0 # next field elif fieldBR > byteBR: shift = fieldBR - byteBR mask = 2 ** byteBR - 1 value = (ord(bytes[curr]) & mask) fieldBR -= byteBR byteBR = 8 curr += 1 # next byte elif fieldBR == byteBR: mask = 2 ** byteBR - 1 value = ord(bytes[curr]) & mask fieldBR -= byteBR byteBR = 8 curr += 1 # next byte real_value += value << fieldBR self.value = real_value return [real_value, curr, byteBR] def encode(self, bytearray, value, byte, byteBR): """encode the a field into the bytes necessary to transmit it as part of a packet bytearray - the array of bytes that will be returned value - the value to encode byte - the byte we are encoding, we can encode partial bytes byteBR - the bits remaining in the current byte being encoded. """ # The algorithm below hurts my head, as I'm not very # smart so it is heavily commented. # # fieldBR is the bits remaining in the field to be encoded # byteBR is the bits remaining in the current byte being encoded # return fast.encode(self.width, bytearray, value, byte, byteBR) fieldBR = self.width while byteBR > 0: if fieldBR < byteBR: shift = byteBR - fieldBR byteBR -= fieldBR mask = ((2 ** fieldBR) - 1) << shift byte = (byte | ((value << shift) & mask)) # Done with the field, not with the byte get new field break elif fieldBR > byteBR: shift = fieldBR - byteBR fieldBR -= byteBR mask = ((2 ** byteBR) - 1) byte = (byte | ((value >> shift) & mask)) bytearray.append(struct.pack('B', byte)) byteBR = 8 byte = 0 # Done with this byte, but not the field, get a new byte elif fieldBR == byteBR: mask = ((2 ** byteBR) - 1) byte = (byte | (value & mask)) bytearray.append(struct.pack('B', byte)) byte = 0 byteBR = 8 # Done with the byte and the field have a nice day break return [byte, byteBR] def set_value(self, value): """Set the value of a field.""" self.value = value def get_value(self): return self.value def reset(self): """Return a resonable value to use in resetting a field of this type.""" return 0 def bounds(self, value): """Check the bounds of this field.""" if ((value is None) or (value < 0) or (value > (2 ** self.width) - 1)): raise FieldBoundsError, "Value must be between 0 and %d but is %d" % ((2 ** self.width - 1), value) def __copy__(self): """Return a shallow copy of a Field; used by copy module. Fields may be copied, they are not immutable.""" return self.__deepcopy__() def __deepcopy__(self, memo={}): """Return a deep copy of a Field; used by copy module. Fields may be copied, they are not immutable; however they always contain integer types which *are* immutable.""" result = self.__class__() memo[id(self)] = result result.__init__(name=self.name, width=self.width, \ default=self.default, \ discriminator=self.discriminator, \ compare=self.compare) # Copy value, we can do so here with impunity -- no __setattr__. result.value = self.value assert result.value == self.value, "value not copied" # The new copy MUST NOT be associated with a Packet. assert result.packet is None, "dangling reference to Packet" return result def default_compare(lp, lf, rp, rf): """Default comparison method. lp - packet on left hand side of comparison lf - field in lp being compared rp - packet on right hand side of comparison rf - field in rp being compared This function is installed in Field.compare on assignment. It is declared static to allow folk to override it with lambda functions. The packets are passed so that back-references to other fields in the packet are possible during the match.""" return lf.value == rf.value default_compare = staticmethod(default_compare) class FieldAlignmentError(Exception): """When a programmer tries to decode a field that is not on a byte boundary this exception is raised.""" def __init__(self, message): """set the FieldAlignmentError message""" ## the message that will be output when this error is raised self.message = message # Both StringField and Field contain only immutable data types, therefore # they share copy semantics through inheritance. class StringField(Field): """A string field is a name, a width in bits, and possibly a default value. The data is to be interpreted as a string, but does not encode the length into the packet. Length encoded values are handled by the LengthValueField.""" def __init__(self, name = "", width = 1, default = None, \ compare = None ): """initialtize a StringField""" self.packet = None ## the name of the StringField self.name = name ## the width, in bits, of the StringField self.width = width ## the default value, if any, of the StringField self.default = default ## the comparison function self.compare = compare ## Fields store the values if default is None: self.value = "" else: self.value = default def __repr__(self): """return a human readable form of a StringFeild object""" return "" % \ (self.name, self.width, self.default) def decode(self, bytes, curr, byteBR): """Decode the field and return the value as well as the new current position in the bytes array.""" # byteBR == 8 is the neutral state if (byteBR is not None and byteBR != 8): raise FieldAlignmentError, "Strings must start on a byte boundary" packarg = "%ds" % (self.width / 8) end = curr + self.width / 8 value = struct.unpack(packarg, bytes[curr:end])[0] curr += self.width / 8 self.value = value return [value, curr, byteBR] def encode(self, bytearray, value, byte, byteBR): """Encode a string field, make sure the bytes are aligned.""" if (byteBR is not None and byteBR != 8): raise FieldAlignmentError, "Strings must start on a byte boundary" packarg = "%ds" % (self.width / 8) bytearray.append(struct.pack(packarg, value)) return [byte, byteBR] def reset(self): """Return a resonable value to use in resetting a field of this type.""" return "" def bounds(self, value): """Check the bounds of this field.""" if (value is None) or (len (value) > (self.width / 8)): raise FieldBoundsError, "Value must be between 0 and %d bytes long" % (self.width / 8) class LengthValueFieldError(Exception): """LengthValue fields only allow access to two internal pieces of data.""" def __init__(self, message): """set the error message""" ## the message that will be output when this error is raised self.message = message # TODO: Add a means of packing fields according to the length actually # encoded in them, where a field has variable length. class LengthValueField(object): """A length value field handles parts of packets where a length and value are encoded together, usually used to shove strings into packets. """ def __init__(self, name, length, value, compare=None): self.packet = None self.name = name self.compare = compare if not isinstance(length, Field): raise LengthValueFieldError, "Length must be of type Field but is %s" % type(length) object.__setattr__(self, 'length', length) if isinstance(value, Field) or isinstance(value, StringField): object.__setattr__(self, 'value', value) else: raise LengthValueFieldError, "Value must be of type Field or StringField but is %s" % type(value) self.width = length.width + value.width #self.packed = packed def __repr__(self): return "" % (self.name, self.type, self.value) def __setattr__(self, name, value): object.__setattr__(self, name, value) if self.packet is not None: self.packet.__needencode = True def decode(self, bytes, curr, byteBR): [self.type.value, curr, byteBR] = self.type.decode(bytes, curr, byteBR) [self.value.value, curr, byteBR] = self.value.decode(bytes, curr, byteBR) return [value, curr, byteBR] def encode(self, bytearray, value, byte, byteBR): [byte, byteBR] = self.type.encode(bytearray, self.type.value, byte, byteBR) [byte, byteBR] = self.value.encode(bytearray, self.value.value, byte, byteBR) return [byte, byteBR] def reset(self): """Return a resonable value to use in resetting a field of this type.""" return "" def bounds(self, value): """Check the bounds of this field.""" if ((value is None) or (len (value) > (((2 ** self.valuewidth) - 1) / 8))): raise FieldBoundsError, "Value must be between 0 and %d bytes long" % (((2 ** self.width) - 1) / 8) # There is no __setattr__ to stomp on us here. def __copy__(self): """Return a shallow copy of a TypeValueField; used by copy module. A shallow copy just makes references to these Fields in the copy.""" result = self.__class__(name=self.name, \ type=self.type, \ value=self.value, \ compare=self.compare) return result def __deepcopy__(self, memo={}): """Return a deep copy of a TypeValueField; used by copy module. A deep copy copies all of the embedded Fields.""" from copy import deepcopy result = self.__class__(name=self.name, \ type=deepcopy(self.type, memo), \ value=deepcopy(self.value, memo), \ compare=self.compare) memo[id(self)] = result return result def default_compare(lp, lf, rp, rf): """Default comparison method.""" return lf.value == rf.value default_compare = staticmethod(default_compare) class TypeLengthValueField(object): """A type-length-value field handles parts of packets where a type is encoded before a length and value. """ def __init__(self, name, type, length, value, inclusive = True, bytewise = True, compare = None): self.packet = None self.name = name if not isinstance(type, Field): raise LengthValueFieldError, "Type must be of type Field but is %s" % type(type) self.type = type if not isinstance(length, Field): raise LengthValueFieldError, "Length must be of type Field but is %s" % type(type) self.length = length if isinstance(value, Field) or isinstance(value, StringField): self.value = value else: raise LengthValueFieldError, "Value must be of type Field or StringField but is %s" % type(value) self.width = type.width + length.width + value.width self.inclusive = inclusive self.bytewise = bytewise self.compare = compare def __repr__(self): return "" \ % (self.type, self.length, self.value) def __setattr__(self, name, value): object.__setattr__(self, name, value) if self.packet is not None: self.packet.__needencode = True def decode(self, bytes, curr, byteBR): [self.type.value, curr, byteBR] = self.type.decode(bytes, curr, byteBR) [self.length.value, curr, byteBR] = self.length.decode(bytes, curr, byteBR) [self.value.value, curr, byteBR] = self.value.decode(bytes, curr, byteBR) return [value, curr, byteBR] def encode(self, bytearray, value, byte, byteBR): """Encode a TypeLengthValue field.""" if isinstance(self.value, Field): # Value is a field. Take its width in bits. self.length.value = self.value.width else: # Value is any other Python type. Take its actual length in bits. self.length.value = len(self.value) * 8 if self.inclusive is True: # Length field includes the size of the type and length fields. self.length.value += (self.type.width + self.length.width) if self.bytewise is True: # Length should be encoded as a measure of bytes, not bits. self.length.value /= 8 [byte, byteBR] = self.type.encode(bytearray, self.type.value, byte, byteBR) [byte, byteBR] = self.length.encode(bytearray, self.length.value, byte, byteBR) [byte, byteBR] = self.value.encode(bytearray, self.value.value, byte, byteBR) return [byte, byteBR] def reset(self): """Return a resonable value to use in resetting a field of this type.""" return "" def bounds(self, value): """Check the bounds of this field.""" if ((value is None) or (len (value) > (((2 ** self.lengthwidth) - 1) / 8))): raise FieldBoundsError, "Value must be between 0 and %d bytes long" % (((2 ** self.width) - 1) / 8) # There is no __setattr__ to stomp on us here. def __copy__(self): """Return a shallow copy of a TypeLengthValueField; used by copy module. A shallow copy just makes references to these Fields in the copy.""" result = self.__class__(name=self.name, \ type=self.type, \ length=self.length, \ value=self.value, \ inclusive=self.inclusive, \ bytewise=self.bytewise, \ compare=self.compare) return result def __deepcopy__(self, memo={}): """Return a deep copy of a TypeLengthValueField; used by copy module. A deep copy copies all of the embedded Fields.""" from copy import deepcopy result = self.__class__(name=self.name, \ type=deepcopy(self.type, memo), \ length=deepcopy(self.length, memo), \ value=deepcopy(self.value, memo), \ inclusive=self.inclusive, \ bytewise=self.bytewise, \ compare=self.compare) memo[id(self)] = result return result def default_compare(lp, lf, rp, rf): """Default comparison method.""" return lf.value == rf.value default_compare = staticmethod(default_compare) class CompoundField(object): """A compound field may contain other fields.""" class OptionListError(Exception): """When a programmer tries to append to an option list and causes an error this exception is raised.""" def __init__(self, message): self.message = message def __str__(self): return repr(self.message) class OptionListField(CompoundField, list): """A option list is a list of Fields. Option lists inhabit many protocols, including IP and TCP.""" def __init__(self, name, width = 0, option_list = [], compare = None): """Iniitialize an OptionListField.""" list.__init__(self) self.packet = None self.name = name self.width = width self._options = [] if option_list != []: for option in option_list: self._options.append(option) self.compare = compare self.default = self self.value = self def __len__(self): return len(self._options) def __iter__(self): self.index = 0 return self def next(self): """Option lists return a pair of (value, option) when iterated""" length = len(self._options) if length <= 0: raise StopIteration if self.index > length: raise StopIteration retval = (self._options[self.index].value) self.index += 1 return retval def __eq__(self, other): """Test two option lists for equality. Two option lists are equal if and only if they have the same options and values.""" if (other is None): return False length = len(self._options) if length != len(other._options): #print "option list lengths differ" return False for i in xrange(length): #print "comparing option list field" f = self._options[i] if isinstance(f, Field): if f.value != other._options[i].value: return False else: #print "option list member ", f.name, "is not a Field" if f != other._options[i]: #print "did not match" return False return True def __ne__(self, other): """test two option lists for inequality""" return not self.__eq__(other) def __repr__(self): return self.__str__() def __str__(self): """return a pretty printed option list""" retval = "[" index = 0 for option in self._options: if isinstance(option, CompoundField): retval += "[Field: %s, Value: %s]" % (option.name, option) else: retval += "[Field: %s, Value: %s]" % (option.name, option.value) if (index == (len(self._options) - 1)): break retval += ", " index += 1 retval += "]" return retval def __setitem__(self, index, value): if (index < 0 or index > len(self._options)): raise IndexError, "index %d out of range" % index else: # Three part harmony # The caller can pass a list of (value, option) if isinstance(value, list): if len(value) != 2: raise OptionListError, "Option must be a pair (value, PCS Field)" if not isinstance(value[1], _fieldlist): raise OptionListError, "Option must be a valid PCS Field." self._options[index] = value[1] self._options[index].value = value[0] return # or the caller can pass a field, but we have to check the # underlying value if isinstance(value, _fieldlist): value.bounds(self._options[index].value) self._options[index] = value return # of the caller can pass a value but we have to check the bounds self._options[index].bounds(value) self._options[index].value = value def __getitem__(self, index): """Return the value of a field in the list.""" if (index < 0 or index > len(self._options)): raise IndexError, "index %d out of range" % index else: return self._options[index].value def bounds(self, value): pass def set_value(self, value): """Set the value of a field.""" self._options = value def __add__(self, other): if isinstance(other, _fieldlist): self._options += other def append(self, option): """Append an option, an option/value pair, or a value to an options list Vaue,Option pairs are given as a list (value, option) """ if not isinstance(option, _fieldlist): raise OptionListError, "Option must be a valid PCS Field." if not hasattr(self, '_options'): self._options = [] self._options.append(option) def encode(self, bytearray, value, byte, byteBR): """Encode all the options in a list into a set of bytes""" if hasattr(self, '_options'): for option in self._options: if isinstance(option, CompoundField): option.encode(bytearray, None, byte, byteBR) else: option.encode(bytearray, option.value, byte, byteBR) return [byte, byteBR] def decode(self, bytes, curr, byteBR): """Decode all the options in the list""" if hasattr(self, '_options'): for option in self._options: if isinstance(option, CompoundField): raise OptionListError, "Can't encode embedded lists yet" else: [value, curr, byteBR] = option.decode(bytes, curr, byteBR) option.value = value return [None, curr, byteBR] def reset(self): print self._options # There is no __setattr__ to stomp on us here. def __copy__(self): """Return a shallow copy of an OptionListField; used by copy module. A shallow copy just makes references to these Fields in the copy.""" result = self.__class__(name=self.name, \ width=self.width, \ option_list=self._options, \ compare=self.compare) return result def __deepcopy__(self, memo={}): """Return a deep copy of an OptionListField; used by copy module. A deep copy copies all of the embedded Fields.""" from copy import deepcopy optcopy = [] for opt in self._options: optcopy.append(deepcopy(opt, memo)) result = self.__class__(name=self.name, \ width=self.width, \ option_list=optcopy, \ compare=self.compare) memo[id(self)] = result return result def default_compare(lp, lf, rp, rf): """Default comparison method.""" return lf == rf # Will use __eq__ defined above. default_compare = staticmethod(default_compare) # Types which implement Field's interface, even if not directly # inherited from Field. User types may inherit from these types. _fieldlist = (Field, StringField, LengthValueField, TypeValueField, TypeLengthValueField, CompoundField) class LayoutDiscriminatorError(Exception): """When a programmer tries to set more than one field in a Layout as a discriminator an error is raised.""" def __init__(self, message): self.message = message def __str__(self): return repr(self.message) class Layout(list): """The layout is a special attribute of a Packet which implements the layout of the packet on the wire. It is actually a list of Fields and is implemented as a descriptor. A layout can only be set or get, but never deleted.""" # No need to implement __deepcopy__, as Layout is a descriptor # modeled on the built-in type 'list' and will propagate deep-copies # to the objects it contains. def __get__(self, obj, typ=None): """return the Layout""" ## the layout is the ordering of the fields in the packet return self._layout # Update the layout itself. Right now this does not handle # removing fields or anything else but must do so in future. # XXX Add code to check the type of the value, it must be a # list of Field objects def __set__(self, obj, value): """set the layout obj - the object we are about to set value - the value we are setting the field to """ self._layout = value for field in self._layout: # This is a special case, we don't want to recurse back # through the encapsulating class's __setattr__ routine. # We want to set this directly in the class's dictionary if not hasattr(field, 'default') or field.default is None: obj.__dict__[field.name] = field.reset() else: obj.__dict__[field.name] = field.default class FieldError(Exception): """When a programmer tries to set a field that is not in the layout this exception is raised.""" def __init__(self, message): """set the error message when this error is raised""" ## the error message passed when this error is raised self.message = message reserved_names = ["_layout", "_discriminator", "_map", "_head"] class Packet(object): """A Packet is a base class for building real packets. Assigning a value to any field of a Packet, whether by keyword argument passed to a constructor, or by using the assignment operator, will cause a default comparison function to be installed. This is to make it easy to specify match filters for Connector.expect(). """ # The layout is a list of fields without values that indicate how # the data in the packet is to be layed in terms of ordering and # bit widths. The update() method, below, uses this list to build # the data in the packet. The actual data is kept in # auto-generated class entries that are built whenever the layout # is changed. A layout is implemented as a descriptor, above, # with only get() and set() methods and so cannot be deleted. # This allows the programmer to set fields in what might be # considered a natural way with a foo.bar = baz type of syntax. # The bytes are the actual bytes in network byte order of a fully # formed packet. Packets are always fully formed as any setting # of a packet field generates a call to the update() method. _bytes = "" def getbytes(self): """return the bytes of the packet""" if self._needencode: self._needencode = False self.encode() return self._bytes # decode must be defined before its used in the property # that is set below it. def decode(self, bytes): """Reset the bytes field and then update the associated attributes of the packet. This method is used when a packet is read in raw form.""" self._bytes = bytes curr = 0 byteBR = 8 length = len(bytes) for field in self._layout: if curr > length: break [value, curr, byteBR] = field.decode(bytes, curr, byteBR) bytes = property(getbytes, decode) def encode(self): """Update the internal bytes representing the packet. This function ought to be considered private to the class.""" # Encode the fields, which are a set of bit widths and values # into a byte string. This is achieved by walking the list of # fields, and then packing them, byte by byte, into a byte # string. The algorithm below hurts my head, as I'm not very # smart so it is heavily commented. # # fieldBR is the bits remaining in the field to be encoded # byteBR is the bits remaining in the current byte being encoded # byteBR = 8 byte = 0 bytearray = [] for field in self._layout: value = self._fieldnames[field.name].value [byte, byteBR] = field.encode(bytearray, value, byte, byteBR) self._bytes = ''.join(bytearray) # Install the new value def __init__(self, layout = None, bytes = None, **kv): """initialize a Packet object layout - the layout of the packet, a list of Field objects bytes - if the packet is being set up now the bytes to set in it kv - if the packet is being set up now, the initial values of each named field, specified as keyword arguments. These are always passed as a dict from classes which inherit from Packet. """ # XXX #self._bytes = "" self._layout = layout self._fieldnames = {} self._head = None for field in layout: self._fieldnames[field.name] = field self._needencode = True if bytes is not None: self.decode(bytes) self._discriminator = None self._discriminator_inited = False # The layout of the Packet, a list of Field objects. for field in layout: field.packet = self if (not hasattr(field, 'discriminator')): continue if ((field.discriminator is True) and (self._discriminator is not None)): raise LayoutDiscriminatorError, "Layout can only have one field marked as a discriminator, but there are at least two %s %s" % (field, self._discriminator) if (field.discriminator is True): self._discriminator = field # Set initial values of Fields using keyword arguments. # Ignore any keyword arguments which do not correspond to # packet fields in the Layout. if kv is not None: for kw in kv.iteritems(): if kw[0] in self._fieldnames: self.__setattr__(kw[0], kw[1]) def __add__(self, layout = None): """add two packets together This is really an append operation, of one packet after another. """ for field in layout: self._layout.append(field) self._needencode = True def __setattr__(self, name, value): """Setting the layout is a special case because of the ramifications this has on the packet. Only fields represented in the layout may be set, no other attributes may be added""" # Handle special fields first. if name == '_fieldnames': object.__setattr__(self, name, value) self._bitlength = 0 for field in self._layout: self._bitlength += field.width return if (hasattr(self, '_fieldnames') and (name in self._fieldnames)): field = self._fieldnames[name] if hasattr(field, 'bounds'): field.bounds(value) field.set_value(value) # If we are setting a field which has no comparison hook, # install the default comparison functor. if field.compare is None: field.compare = field.default_compare # If the field we're initializing is the discriminator field, # record that we have initialized it, so that the / operator # will not clobber its value. if self._discriminator is not None and \ name == self._discriminator.name: self._discriminator_inited = True self._needencode = True else: object.__setattr__(self, name, value) def __getattribute__(self, name): """Getting an attribute means we may have extended an option. If we append to an options list we have to reencode the bytes.""" object.__setattr__(self, '_needencode', True) try: fieldnames = object.__getattribute__(self, '_fieldnames') except: return {} if name in fieldnames: if isinstance(fieldnames[name], Field) and not \ isinstance(fieldnames[name], (LengthValueField, TypeValueField, TypeLengthValueField)): return fieldnames[name].get_value() else: return fieldnames[name] return object.__getattribute__(self, name) def __eq__(self, other): """Do a comparison of the packets data, including fields and bytes.""" if (type(self) != type(other)): return False if (self.bytes != other.bytes): return False for field in self._layout: if self._fieldnames[field.name].value != other._fieldnames[field.name].value: return False return True def __ne__(self, other): """Do a comparison of the packets data, including fields and bytes.""" return not self.__eq__(other) def matches(self, other): """Return True if the packets match. Each contains a reference to a comparison function. If the reference is None, we assume no comparison need be performed. This allows full flexibility in performing matches.""" if not isinstance(other, self.__class__): #if __debug__: # print "Skipping match: isinstance(%s,%s) is False" % \ # (type(self), type(other)) return False nocomps = True for fn in self._layout: f = self._fieldnames[fn.name] if f.compare is None: continue nocomps = False #if __debug__ and f.compare is not f.default_compare: # print "WARNING: %s.%s not using default_compare." % \ # (type(self), fn.name) #if __debug__ and isinstance(f, Field): # print " comparing", f.value, "with", other._fieldnames[fn.name].value if not f.compare(self, f, other, other._fieldnames[fn.name]): return False #if __debug__ and nocomps is True: # print "WARNING: no comparisons were made" return True def wildcard_mask(self, fieldnames=[], unmask=True): """Mark or unmark a list of fields in this Packet as wildcard for match(). If unmask is false, then apply a default comparison function specific to the class of the Field. If an empty list is passed, apply the mask to all fields.""" if fieldnames == []: fieldnames = self._fieldnames.keys() for i in fieldnames: field = self._fieldnames[i] if unmask is True: field.compare = None else: field.compare = field.default_compare def __repr__(self): """Walk the entire packet and return the values of the fields.""" #print "Packet.__repr__() called" if hasattr(self, 'description'): name = self.description else: name = 'Packet' return '<%s: %s>' % (name, ', '.join(attribreprlist(self, self._layout.__iter__()))) def println(self): """Print the packet in line format.""" return self.__repr__() def __str__(self): """Pretty print, with returns, the fields of the packet.""" #print "Packet.__str__() called" retval = "" if hasattr(self, 'description'): retval += "%s\n" % self.description for field in self._layout: retval += "%s %s\n" % (field.name, self._fieldnames[field.name].value) #for field in self._layout: # retval += "%s %s\n" % (field.name, field.value) return retval def __len__(self): """Return the count of the number of bytes in the packet.""" return len(self.bytes) def __div__(self, packet): """/ operator: Insert a packet after this packet in a chain. If I am not already part of a chain, build one. If the discriminator field in this packet has not been explicitly initialized, either by assignment or by constructor keyword arguments, then attempt to initialize it based on the type of the packet being appended. The packet being appended will have its head pointer overwritten to point to the chain it is being appended to. The head of the chain is always returned.""" if not isinstance(packet, Packet): raise exceptions.TypeError if self._head is None: head = self.chain() if self._discriminator_inited is not True: self.rdiscriminate(packet) head.append(packet) self._head = head packet._head = head else: head = self._head if not isinstance(head, Chain): raise exceptions.TypeError if head.insert_after(self, packet) is False: raise exceptions.IndexError packet._head = head return head def __copy__(self): """Return a shallow copy of a Packet; used by copy module. This is always implemented as a deep copy.""" return self.__deepcopy__() def __deepcopy__(self, memo={}): """Return a deep copy of a Packet; used by copy module. All derived classes of Packet create a new instance of Layout and what it contains every time they are constructed. We need to preserve that API contract down here in the lower layers; and we need to return an instance of the derived class, so we call its default constructor, and make a deep copy of all the field values here. The backing store in self.bytes is an immutable buffer which is dynamically reallocated when changed, so we can either copy it or forget about it.""" from copy import deepcopy newp = self.__class__() for field in newp._layout: newp._fieldnames[field.name] = \ deepcopy(self._fieldnames[field.name], memo) memo[id(self)] = newp return newp def chain(self): """Return the packet and its next packets as a chain.""" chain = Chain([]) packet = self done = False while not done: packet._head = chain chain.append(packet) if packet.data is not None: packet = packet.data else: done = True return chain def next(self, bytes, discriminator = None, timestamp = None): """Demultiplex higher layer protocols based on a supplied map and discriminator field.""" # If the caller passes their own discriminator then we use the # caller's otherwise we use the one built into the packet. # The use of a caller supplied discriminator allows use to # more easily unpack packets that are chunked, where the # current packet does not contain knowledge about what comes # next. if ((discriminator is not None) and (self._map is not None)): if (discriminator in self._map): return self._map[self._fieldnames[discriminator.name].value](bytes, timestamp = timestamp) if ((self._discriminator is not None) and (self._map is not None)): if (self._fieldnames[self._discriminator.name].value in self._map): return self._map[self._fieldnames[self._discriminator.name].value](bytes, timestamp = timestamp) return None def rdiscriminate(self, packet, discfieldname = None, map = None): """Reverse-map an encapsulated packet back to a discriminator field value. Given a following packet which is about to be appended or inserted in a chain, look at its type, and fill out the discriminator field. This is 'reverse discrimination', as we are mapping a packet type back to a code field, which means a reverse dict lookup. The mapping may not be 1:1, in which case we simply return the first match; isinstance() is used to match derived classes. Individual packet classes should override this if they need to return a particular flavour of an encapsulated packet, or force a lookup against a map which isn't part of the class. This is provided as syntactic sugar, used only by the / operator. If we find a match, and set the discriminator field, we will also set its compare function to the default for the field's class if a comparison function was not already specified. Return True if we made any changes to self.""" if (not isinstance(packet, Packet)): raise exceptions.TypeError # If we were not passed discriminator field name and map, try # to infer it from what's inside the instance. if map is None: if not hasattr(self, '_map') or self._map is None: return False map = self._map if discfieldname is None: if self._discriminator is None: return False discfieldname = self._discriminator.name for i in map.iteritems(): if isinstance(packet, i[1]): field = self._fieldnames[discfieldname] field.value = i[0] if field.compare is None: field.compare = field.default_compare return True return False def calc_checksum(self): """Compute checksum for this packet. The base class does nothing, it has no notion of checksum.""" #print "Packet.calc_checksum()" pass def calc_length(self): """Compute length field for this packet. The base class does nothing, it has no notion of a length field.""" pass def sizeof(self): """Return the size, in bytes, of the packet.""" return (self._bitlength / 8) def toXML(self): """Transform the Packet into XML.""" pass def fromXML(self): """Create a Packet from XML.""" pass def toHTML(self): """Transform a Packet to HTML.""" pass def fromHTML(self): """Create a Packet from HTML.""" pass class Chain(list): """A chain is simply a list of packets. Chains are used to aggregate related sub packets into one chunk for transmission.""" def __init__(self, packets=[]): """initialize a Chain object packets - an optional list of packets to add to the new Chain """ list.__init__(self) self.packets = packets for p in self.packets: # XXX We may clobber packets which belong to an existing Chain. #if __debug__ and p._head is not None: # print "WARNING: clobbering head pointer" p._head = self self.encode() def __eq__(self, other): """test two Chain objects for equality Two chains are equal iff they have the same packets and their packets have the same data in them.""" if len(self.packets) != len(other.packets): return False length = len(self.packets) for i in xrange(length): if self.packets[i] != other.packets[i]: return False return True def __ne__(self, other): """test two Chain objects for inequality""" return not self.__eq__(other) def __str__(self): """return a pretty printed Chain""" #print "Chain.__str__() called" #self.encode() retval = "" for packet in self.packets: retval += "%s " % packet.__str__() return retval def __repr__(self): #print "Chain.__repr__() called" return self.packets.__repr__() def __div__(self, packet, rdiscriminate=True): """/ operator: Append a packet to the end of a chain. The packet's head pointer will be overwritten to point to this chain. The default behaviour is to fill out the discriminator field of the packet in front of the new tail packet.""" if not isinstance(packet, Packet): raise exceptions.TypeError if rdiscriminate is True: # Don't clobber a previously initialized field. if self.packets[-1]._discriminator_inited is not True: self.packets[-1].rdiscriminate(packet) self.append(packet) packet._head = self return self def __copy__(self): """Return a shallow copy of a Chain; used by copy module. This is always implemented as a deep copy.""" return self.__deepcopy__() def __deepcopy__(self, memo={}): """Return a deep copy of a Chain; used by copy module. Chain is derived from list. We can't rely on the default deepcopy handler for list, as it doesn't know our representation. Chain may contain Packets, and Packets may refer back to their parent Chain. Because of this, we need to make deep copies of all Packets contained within a Chain to avoid clobbering the contents of existing Chains, and set their head pointer to point to the newly created Chain. Also, the constructor for Chain needs a list of Packet, so we pass it an empty list and then append each copied Packet to its internal list.""" from copy import deepcopy newchain = self.__class__([]) memo[id(self)] = newchain for p in self.packets: newp = deepcopy(p, memo) newp._head = newchain newchain.packets.append(newp) newchain.encode() return newchain def append(self, packet): """Append a packet to a chain. Appending a packet requires that we update the bytes as well.""" self.packets.append(packet) self.encode() def insert_after(self, p1, p2, rdiscriminate=True): """Insert a packet into a chain after a given packet instance. Used only by the div operator. The default behaviour is to set discriminator fields in p1 based on p2.""" length = len(self.packets) for i in xrange(length): if self.packets[i] is p1: if rdiscriminate is True: p1.rdiscriminate(p2) self.packets.insert(i, p2) self.encode() return True return False def contains(self, packet): """If this chain contains a packet which matches the packet provided, return its index. Otherwise, return None. It is assumed that 'packet' contains any wildcard patterns; this is the logical reverse of Field.match() and Packet.match(). A bitwise comparison is not performed; a structural match using the match() function is used instead.""" (p, i) = self.find_first_of(type(packet)) if p is not None and packet.matches(p): return i return None def matches(self, chain): """Return True if this chain matches the chain provided. It is assumed that *this* chain contains any wildcard patterns. A strict size comparison is not performed. A bitwise comparison is not performed; a structural match using the match() function is used instead.""" if len(self.packets) > len(chain.packets): #print "Skipping: packet header counts don't match" return False i = 0 for p in self.packets: #print "comparing %s", type(p) if not p.matches(chain.packets[i]): return False i += 1 return True def wildcard_mask(self, unmask=True): """Mark or unmark all of the fields in each Packet in this Chain as a wildcard for match() or contains().""" length = len(self.packets) for i in xrange(length): self.packets[i].wildcard_mask([], unmask) def encode(self): """Encode all the packets in a chain into a set of bytes for the Chain""" self.bytes = "" for packet in self.packets: self.bytes += packet.bytes def decode(self, bytes): """Decode all the bytes of all the packets in a Chain into the underlying packets""" for packet in self.packets: packet.decode(packet.bytes) # XXX We are a model of list so if we proxy this to member # self.packets this can be renamed index() and go away. def index_of(self, packet): """Return the index of 'packet' in this chain.""" n = 0 for i in self.packets: if i is packet: pseen = True break n += 1 #print "index of %s is %d" % (type(packet), n) assert pseen is True, "Chain inconsistent: packet not found" return n def collate_following(self, packet): """Given a packet which is part of this chain, return a string containing the bytes of all packets following it in this chain. Helper method used by Internet transport protocols.""" tmpbytes = "" n = self.index_of(packet) if n == len(self.packets)-1: return tmpbytes for p in self.packets[n+1:]: #print "collating %s" % (type(p)) tmpbytes += p.getbytes() return tmpbytes def find_first_of(self, ptype): """Find the first packet of type 'ptype' in this chain. Return a tuple (packet, index).""" n = 0 for p in self.packets: if isinstance(p, ptype): return (p, n) n += 1 return (None, None) def find_preceding(self, packet, ptype, adjacent=True): """Given a packet which is part of this chain, return a reference to a packet of the given type which precedes this packet, and its index in the chain, as a tuple. If the 'adjacent' argument is True, then the packet immediately preceding 'packet' must be an instance of type. Helper method used by Internet transport protocols.""" n = self.index_of(packet) if n == 0: return (None, None) lower = 0 if adjacent is True: lower = max(n - 2, 0) for p in reversed(self.packets[lower:n]): n -= 1 if isinstance(p, ptype): return (p, n) return (None, None) def calc_checksums(self): """Compute and store checksums for all packets in this chain, taking encapsulation into account. By default the packets are enumerated in reverse order to how they appear on the wire. This is how IETF-style protocols are normally dealt with; ITU-style protocols may require other quirks.""" #print "Chain.calc_checksum()" for packet in reversed(self.packets): packet.calc_checksum() def calc_lengths(self): """Compute and store length fields for all packets in this chain, taking encapsulation into account. """ for packet in reversed(self.packets): packet.calc_length() def fixup(self): """Convenience method to calculate lengths, checksums, and encode.""" self.calc_lengths() self.calc_checksums() self.encode() class ConnNotImpError(Exception): """Calling a method that is not implemented raises this exception. The base class, and some of the derived classes do not implement every moethod that could be. This exception is meant to catch and report thos instances. """ def __init__(self, message): self.message = message class EOFError(Exception): """If the I/O handle was closed, or end of file seen, raise this exception. """ def __init__(self, message='End of file'): self.message = message class LimitReachedError(Exception): """If a packet input threshold is reached, raise this exception. """ def __init__(self, message='Limit reached'): self.message = message class TimeoutError(Exception): """If a possibly blocking read operation times out, this exception will be raised. """ def __init__(self, message='Timed out'): self.message = message class UnpackError(Exception): """Error raised when we fail to unpack a packet.""" def __init__(self, message): self.message = message class EOF(object): """This type allows end-of-file to be matched as a pattern by expect().""" def __init__(self): pass class TIMEOUT(object): """This type allows timeouts to be matched as a pattern by expect().""" def __init__(self): pass class LIMIT(object): """This type allows 'limit reached' to be matched by expect().""" def __init__(self): pass class Connector(object): """Connectors are a way of have a very generic socket like mechanism over which the packets can be sent. Unlike the current split between sockets, which work OK down to almost the RAW layer, and low level stuff like pcap and bpf, connectors will are a unifying mechanism so you can write packets over any of the available APIs and the connector will do the right thing. The Connector class is a virtual base class upon which all the real classes are based.""" def __init__(self): self.matches = None self.match_index = None # XXX Can't do protected constructors in Python. #raise ConnNotImpError, "Cannot use base class" def accept(self): raise ConnNotImpError, "Cannot use base class" def bind(self): raise ConnNotImpError, "Cannot use base class" def connect(self): raise ConnNotImpError, "Cannot use base class" def listen(self): raise ConnNotImpError, "Cannot use base class" def read(self): raise ConnNotImpError, "Cannot use base class" def poll_read(self, timeout): """Poll the underlying I/O layer for a read. Return TIMEOUT if the timeout was reached.""" raise ConnNotImpError, "Cannot use base class" def read_packet(self): """Read a packet from the underlying I/O layer, and return an instance of a class derived from pcs.Packet appropriate to the data-link or transport layer in use. If the Connector has multiple data-link layer support, then the type returned by this method may vary. If the underlying packet parsers throw an exception, it will propagate here. """ raise ConnNotImpError, "Cannot use base class" def read_chain(self): """Read the next available packet and attempt to decapsulate all available layers of encapsulation into Python objects. If the underlying packet parsers throw an exception, it will propagate here.""" p = self.read_packet() return p.chain() def try_read_n_chains(self, n): """Try to read at most n packet chains from the underlying I/O layer. If n is None or 0, try to read exactly one packet. Connectors with their own buffering semantics should override this method (e.g. PcapConnector). Used by expect().""" result = [] if n is None or n == 0: n = 1 for i in xrange(n): p = self.read_packet() if p is not None: c = p.chain() result.append(c) else: break return result def write(self): raise ConnNotImpError, "Cannot use base class" def send(self): raise ConnNotImpError, "Cannot use base class" def sendto(self): raise ConnNotImpError, "Cannot use base class" def recv(self): raise ConnNotImpError, "Cannot use base class" def recvfrom(self): raise ConnNotImpError, "Cannot use base class" def close(self): raise ConnNotImpError, "Cannot use base class" def expect(self, patterns=[], timeout=None, limit=None): """Read from the Connector and return the index of the first pattern which matches the input chain; otherwise, raise an exception. On return, the matches property will contain a list of matching packet chain(s). There may be more than one match if a live capture matches more than one before the loop exits. * If the 'limit' argument is set, raise an exception after 'limit' packets have been read, regardless of match. * If 'timeout' is set, raise an exception after the timeout expires. This is only supported if the underlying Connector fully implements non-blocking I/O. The syntax is intentionally similar to that of pexpect: * If any of EOF, LIMIT or TIMEOUT are specified, the exceptions are not raised but are instead matched as patterns. * If a Chain is specified, it is matched against the chain using the Chain.match() method. * If neither a timeout or a limit is specified, or an EOF was not encountered, this function may potentially block forever. * NOTE: Packets can no longer be specified on their own as filters. TODO: Make this drift and jitter robust (CLOCK_MONOTONIC).""" from time import time start = time() then = start remaining = limit delta = timeout self.matches = None self.match_index = None while True: result = self.poll_read(delta) # Compute the wait quantum for the next read attempt. if timeout is not None: now = time() delta = now - then then = now # Check if the user tried to match exceptional conditions # as patterns. We need to check for timer expiry upfront. length = len(patterns) if timeout is not None and (now - start) > timeout: for i in xrange(length): if isinstance(patterns[i], TIMEOUT): self.matches = [patterns[i]] self.match_index = i return i raise TimeoutError if isinstance(result, TIMEOUT): if delta > 0: #print "woken up early" continue if isinstance(result, EOF): for i in xrange(length): if isinstance(patterns[i], EOF): self.matches = [patterns[i]] self.match_index = i return i raise EOFError # Try to read as many pending packet chains as we can; some # Connectors override this as their I/O layers expect to return # multiple packets at once, and reentering Python might lose # a race with the ring buffer (e.g. pcap_dispatch()). chains = self.try_read_n_chains(remaining) next_chain = 0 matches = [] match_index = None # Check for a first match in the filter list. # If we exceed the remaining packet count, break. for i in xrange(len(chains)): c = chains[i] #print "expect() firstpass: saw", str(type(c.packets[2]))[:-2].split('.')[-1] if limit is not None: remaining -= 1 for j in xrange(length): filter = patterns[j] if isinstance(filter, Chain) and filter.matches(c): #print "matched at index", i #print "appending ip proto ", c.packets[1].protocol, \ # "with type ", type(c.packets[2]), "as match" matches.append(c) match_index = j next_chain = i+1 break # We need to break out of the outer loop too if we match. if match_index is not None or \ limit is not None and remaining == 0: break # If one of our filters matched, try to match all the other # packets we got in a batch from a possibly live capture. if match_index is not None: filter = patterns[match_index] #print "scanning", next_chain, "to", len(chains) for i in xrange(next_chain, len(chains)): c = chains[i] #print "expect() lastpass: saw", str(type(c.packets[2]))[:-2].split('.')[-1] if isinstance(filter, Chain) and filter.matches(c): #print "matched at index", i #print "appending ip proto ", c.packets[1].protocol, \ # "with type ", type(c.packets[2]), "as match" matches.append(c) self.matches = matches self.match_index = match_index return match_index # If we never got a match, and we reached our limit, # return an error. if limit is not None and remaining == 0: for i in xrange(length): if isinstance(patterns[i], LIMIT): self.matches = [patterns[i]] self.match_index = i return i raise LimitReachedError #print "next expect() iteration" return None class PcapConnector(Connector): """A connector for protocol capture and injection using the pcap library The Pcap connector looks like all the rest of the connectors for PCS with the differnece that it provides direct network access and bypasses all the protocol stacks on a system. The usual precautions about routing, framing and the like apply so do not use this connector if you're not prepared to do all the protocol work on your own. """ def __init__(self, name=None, snaplen=65535, promisc=True, \ timeout_ms=500): """initialize a PcapConnector object name - the name of a file or network interface to open snaplen - maximum number of bytes to capture for each packet promisc - boolean to specify promiscuous mode sniffing timeout_ms - read timeout in milliseconds """ super(PcapConnector, self).__init__() try: self.file = pcap.pcap(name, snaplen, promisc, timeout_ms) except: raise # Grab the underlying pcap objects members for convenience self.dloff = self.file.dloff self.setfilter = self.file.setfilter self.dlink = self.file.datalink() # Default to blocking I/O. self.file.setnonblock(False) self.is_nonblocking = False def read(self): """read a packet from a pcap file or interface returns the packet as a bytearray """ return self.file.next()[1] def recv(self): """recv a packet from a pcap file or interface""" return self.file.next()[1] def recvfrom(self): """recvfrom a packet from a pcap file or interface""" return self.file.next()[1] def setdirection(self, inout): """Set the pcap direction.""" return self.file.setdirection(inout) def poll_read(self, timeout=None): """Poll the underlying I/O layer for a read. Return TIMEOUT if the timeout was reached.""" from select import select fd = self.file.fileno() # Switch to non-blocking mode if entered without. if not self.is_nonblocking: self.file.setnonblock(True) result = select([fd],[],[], timeout) # Restore non-blocking mode if entered without. if not self.is_nonblocking: self.file.setnonblock(False) if not fd in result[0]: return TIMEOUT() return None def read_packet(self): (timestamp, packet) = self.file.next() return self.unpack(packet, self.dlink, self.dloff, timestamp) def readpkt(self): # XXX legacy name. return self.read_packet() def try_read_n_chains(self, n): """Try to read at most n packet chains from the pcap session. Used by Connector.expect() to do the right thing with buffering live captures.""" if n is None or n == 0: n = -1 # pcap: process all of the buffer in a live capture result = [] # list of chain ltp = [] # list of tuple (ts, packet) def handler(ts, p, *args): ltp = args[0] ltp.append((ts, p)) self.file.dispatch(n, handler, ltp) #print "PcapConnector.try_read_n_chains() read ", len(ltp) for tp in ltp: p = self.unpack(tp[1], self.dlink, self.dloff, tp[0]) c = p.chain() result.append(c) return result def expect(self, patterns=[], timeout=None, limit=None): """PcapConnector needs to override expect to set it up for non-blocking I/O throughout. We do this to avoid losing packets between expect sessions. Typically we would also set up pcap filter programs here if performing potentially expensive matches.""" oldnblock = self.is_nonblocking if oldnblock is False: self.file.setnonblock(True) self.is_nonblocking = True result = Connector.expect(self, patterns, timeout, limit) if oldnblock is False: self.file.setnonblock(False) self.is_nonblocking = False return result def write(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object """ return self.file.inject(packet, bytes) def send(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object""" return self.file.inject(packet, bytes) def sendto(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object""" return self.file.inject(packet, bytes) def unpack(self, packet, dlink, dloff, timestamp): """Create a Packet from a string of bytes. packet - a Packet object dlink - a data link layer as defined in the pcap module dloff - a datalink offset as defined in the pcap module """ import packets.ethernet import packets.localhost if dlink == pcap.DLT_EN10MB: return packets.ethernet.ethernet(packet, timestamp) elif dlink == pcap.DLT_NULL: return packets.localhost.localhost(packet, timestamp) else: raise UnpackError, "Could not interpret packet" def close(self): """Close the pcap file or interface.""" self.file.close() def set_bpf_program(self, prog): from pcs.bpf import program if not isinstance(prog, program): raise ValueError, "not a BPF program" return self.file.setbpfprogram(prog) # The intention is to offload some, but not all, of the filtering work # from PCS to PCAP using BPF as an intermediate representation. # Only add BPF match opcodes for discriminator fields which satisfy # certain criteria. # Relative branches are forward only up to 256 instructions. # The length of each packet header may not be constant if optional # fields are present in filter chain, so calculate offset into # chain using getbytes() not sizeof(). # XXX We always assume a datalink header is present in the chain. def make_bpf_program(c): """Given a filter chain c, create a simple BPF filter program.""" from pcs.bpf import program, ldw, ldb, ldh, jeq, ret assert isinstance(c, Chain) # XXX It seems necessary to compute offsets in bits. At the # moment this code does no special handling of bytes within # BPF's 32-bit words. foff = 0 prog = program() for p in c.packets: for fn in p._layout: f = p._fieldnames[fn.name] #print "foff: ", foff if isinstance(f, Field) and \ f.compare is f.default_compare and \ f.discriminator is True and (f.width % 8) == 0: if f.width == 8: prog.instructions.append(ldb(foff>>3)) elif f.width == 16: prog.instructions.append(ldh(foff>>3)) elif f.width == 32: prog.instructions.append(ldw(foff>>3)) prog.instructions.append(jeq(0, 0, f.value)) foff += f.width prog.instructions.append(ret(96)) prog.instructions.append(ret(0)) jfabs = len(prog.instructions) - 1 ii = 0 # Relative branch displacements are measured from the address of # the following opcode. for i in prog.instructions: ii += 1 if isinstance(i, jeq): assert ((jfabs - ii) <= 255), "Relative branch overflow." i.jf = jfabs - ii return prog make_bpf_program = staticmethod(make_bpf_program) class PcapDumpConnector(Connector): """A connector for dumping packets to a file for later re-use. The PcapDump connector allows the programmer to write libpcap compatible files full of packets. Unlike the PcapConnector it does not alloww the programmer to read from a dump file, for that the PcapConnector class should be used. """ def __init__(self, dumpfile = None, dumptype = None): """initialize a pcap dump connector""" from pcap import pcap try: self.file = pcap(dumpfile = dumpfile, dumptype=dumptype) except: raise # Grab the underlying pcap objects members for convenience self.dloff = self.file.dloff self.setfilter = self.file.setfilter def write(self, packet): """write a packet to the dumpfile""" if type(packet) is buffer: packarg = "%ds" % len(packet) packet = struct.unpack(packarg, packet)[0] return self.file.dump(packet) def send(self, packet): """send a packet to the dumpfile calls the write() method""" return self.file.dump(packet) def sendto(self, packet, header): """sendto a packet to the dumpfile calls the write() method""" return self.file.dump(packet) def close(self): """close the dumpfile""" self.file.dump_close() class TapConnector(Connector): """A connector for capture and injection using the character device slave node of a TAP interface. Like PcapConnector, reads are always blocking, however writes may always be non-blocking. The underlying I/O is non-blocking; it is hard to make it work with Python's buffering strategy for file(), so os-specific reads/writes are used. No filtering is currently performed, it would be useful to extend pcap itself to work with tap devices. """ def __init__(self, name): """initialize a TapConnector object name - the name of a file or network interface to open """ import os from os import O_NONBLOCK, O_RDWR self.is_nonblocking = False try: self.fileno = os.open(name, O_RDWR) except: raise def read(self): """read a packet from a tap interface returns the packet as a bytearray """ return self.blocking_read() def recv(self): """recv a packet from a tap interface""" return self.blocking_read() def recvfrom(self): """recvfrom a packet from a tap interface""" return self.blocking_read() def read_packet(self): """Read a packet from a pcap file or interfaces returning an appropriate packet object.""" bytes = self.blocking_read() return packets.ethernet.ethernet(bytes) def readpkt(self): # XXX legacy name. return self.read_packet() def write(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object """ return self.blocking_write(packet) def send(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object""" return self.blocking_write(packet) def sendto(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object""" return self.blocking_write(packet) # XXX We could just call PcapConnector's method here. def poll_read(self, timeout=None): """Poll the underlying I/O layer for a read. Return TIMEOUT if the timeout was reached.""" from select import select fd = self.file.fileno() # Switch to non-blocking mode if entered without. if not self.is_nonblocking: self.file.setnonblock(True) result = select([fd],[],[], timeout) # Restore non-blocking mode if entered without. if not self.is_nonblocking: self.file.setnonblock(False) if not fd in result[0]: return TIMEOUT() return None def try_read_n_chains(self, n): """Try to read as many packet chains from the tap device as are currently available. Used by Connector.expect() to do the right thing with buffering live captures. Note that unlike pcap, timestamps are not real-time.""" from time import time result = [] # list of chain lpb = [] # list of strings (packet buffers) if __debug__ and not self.is_nonblocking: print "WARNING: TapConnector.try_read_n_chains w/o O_NONBLOCK" ts = time() for i in xrange(n): pb = self.try_read_one() if pb is None: break lpb.append(pb) for pb in lpb: p = self.unpack(pb, self.dlink, self.dloff, ts) c = p.chain() result.append(c) return result # XXX We could just call PcapConnector's method here. def expect(self, patterns=[], timeout=None, limit=None): """TapConnector needs to override expect just like PcapConnector does.""" # Force non-blocking mode. oldnblock = self.is_nonblocking if oldnblock is False: self.setnonblock(True) self.is_nonblocking = True # Call base class expect() routine. result = Connector.expect(self, patterns, timeout, limit) # Unconditionally restore O_NBLOCK mode. self.setnonblock(oldnblock) self.is_nonblocking = oldnblock return result def setnonblock(enabled): """Set the non-blocking flag. Return the value of the file flags.""" from os import O_NONBLOCK from fcntl import fcntl, F_SETFL, F_GETFL flags = fcntl(self.fileno, F_GETFL) if ((flags & O_NONBLOCK) == O_NONBLOCK) != enabled: flags ^= O_NONBLOCK if fcntl(self.fileno, F_SETFL, flags) == -1: raise OSError, "fcntl" return flags def write(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object""" return self.file.inject(packet, bytes) def send(self, packet, bytes): """Write a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object""" return self.file.inject(packet, bytes) def blocking_read(self): """Block until the next packet arrives and return it.""" # Force a blocking read. oldnblock = self.is_nonblocking if oldnblock is True: self.setnonblocking(False) self.is_nonblocking = False poll_read(None) result = try_read_one(self) # Unconditionally restore O_NBLOCK mode. self.setnonblocking(oldnblock) self.is_nonblocking = oldnblock return result def try_read_one(self): """Low-level non-blocking read routine, tries to read the next frame from the tap.""" import array import fcntl import os from termios import FIONREAD try: buf = array.array('i', [0]) s = fcntl.ioctl(self.fileno, FIONREAD, buf) qbytes = buf.pop() if qbytes == 0: return None return os.read(self.fileno, qbytes) except: raise return None def blocking_write(self, bytes): import os # Force a blocking write. oldnblock = self.is_nonblocking if oldnblock is True: self.setnonblocking(False) self.is_nonblocking = False result = os.write(self.fileno, bytes) # Unconditionally restore O_NBLOCK mode. self.setnonblocking(oldnblock) self.is_nonblocking = oldnblock return result def close(self): import os os.close(self.fileno) class IP4Connector(Connector): """Base class for all IPv4 connectors. This class implements all the necessary functions for a plain IPv4 based connector. In particular the data access methods, such as read, write, etc. likely do not need to be overridden by the sub classes. """ def __init__(self, name = None): """initialize an IP4Connector""" try: self.file = socket(AF_INET, SOCK_RAW, IPPROTO_IP) except: raise def connect(self, address): """connect to a foreign IPv4 address""" return self.file.connect(address) def read(self, len): """read data from an IPv4 socket""" return self.file.recv(len) def read_packet(self): bytes = self.file.read() return packets.ipv4.ipv4(bytes) def recv(self, len, flags = 0): """recv data from an IPv4 socket""" return self.file.recv(len, flags) def recvfrom(self, len, flags = 0): """recvfrom data from an IPv4 socket""" return self.file.recvfrom(len, flags) def write(self, packet, flags = 0): """write data to an IPv4 socket""" return self.file.sendall(packet, flags) def send(self, packet, flags = 0): """send data to an IPv4 socket""" return self.file.send(packet, flags) def sendto(self, packet, addr, flags = 0): """sendto data to an IPv4 socket""" return self.file.sendto(packet, flags, addr) def close(self): """close an IPv4 Connector""" self.file.close() class UDP4Connector(IP4Connector): """A connector for IPv4 UDP sockets """ def __init__(self, address = None, port = None): """initialize a UDPv4 connector address - an optional address to connect to port - an optional port to connect to """ try: self.file = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) except: raise if (address is not None and port is not None): try: self.file.connect((address, port)) except: raise class TCP4Connector(IP4Connector): """A connector for IPv4 TCP sockets The TCP4Connector implements a IPv4 TCP connection """ def __init__(self, addr = None, port = None ): """initialize a TCP4Connector class for TCP over IPv4""" try: self.file = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) except: raise if (addr is not None and port is not None): try: self.file.connect((addr, port)) except: raise class UmlMcast4Connector(UDP4Connector): """A connector for hooking up to a User Mode Linux virtual LAN, implemented by Ethernet frames over UDP sockets in a multicast group. Typically used for interworking with QEMU. See: http://user-mode-linux.sourceforge.net/old/text/mcast.txt No additional encapsulation of the frames is performed, nor is any filtering performed. Be aware that this encapsulation may fragment traffic if sent across a real LAN. The multicast API is being somewhat abused here to send and receive the session on the same socket; generally apps shouldn't bind to group addresses, and it's not guaranteed to work with all host IP stacks. """ def __init__(self, group, port, ifaddr = None): """initialize a UML Mcast v4 connector group - the multicast group to join port - the UDP source/destination port for the session ifaddr - optionally, the interface upon which to join the group. """ import os import fcntl from os import O_NONBLOCK from fcntl import F_GETFL, F_SETFL if ifaddr is None: ifaddr = "127.0.0.1" try: self.group = group self.port = int(port) self.file = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP) flags = fcntl.fcntl(self.file, F_GETFL) flags |= O_NONBLOCK fcntl.fcntl(self.file, F_SETFL, flags) self.file.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1) self.file.setsockopt(IPPROTO_IP, IP_MULTICAST_LOOP, 1) gaddr = inet_atol(self.group) mreq = struct.pack('!LL', gaddr, inet_atol(ifaddr)) self.file.setsockopt(IPPROTO_IP, IP_ADD_MEMBERSHIP, mreq) self.file.bind((self.group, self.port)) except: raise def read_packet(self): bytes = self.blocking_read() return packets.ethernet.ethernet(bytes) def readpkt(self): # XXX legacy name. return self.read_packet() def poll_read(self, timeout=None): from select import select fd = self.file.fileno() result = select([fd],[],[], timeout) if not fd in result[0]: return TIMEOUT() return None def blocking_read(self): # XXX Should use recvfrom. # XXX Shouldn't have to guess buffer size. import os poll_read(None) return os.read(self.file.fileno(), 1502) def write(self, packet, flags = 0): """write data to an IPv4 socket""" return self.file.sendto(packet, flags, (self.group, self.port)) class SCTP4Connector(IP4Connector): """A connector for IPv4 SCTP sockets The TCP4Connector implements a IPv4 SCTP connection """ def __init__(self, addr = None, port = None ): """initialize a SCTP4Connector class for TCP over IPv4""" try: self.file = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP) except: raise if (addr is not None and port is not None): try: self.file.connect((addr, port)) except: raise class IP6Connector(Connector): """Base class for all IPv6 connectors. This class implements all the necessary functions for a plain IPv6 based connector. In particular the data access methods, such as read, write, etc. likely do not need to be overridden by the sub classes. """ def __init__(self, name = None): """initialize an IPPConnector class for raw IPv6 access""" try: self.file = socket(AF_INET6, SOCK_RAW, IPPROTO_IP) except: raise def read(self, len): """read from an IPv6 connection""" return self.file.recv(len) def read_packet(self): bytes = self.file.read() return packets.ipv6.ipv6(bytes) def recv(self, len, flags = 0): """recv data from an IPv4 socket""" return self.file.recv(len, flags) def recv(self, len, flags = 0): """recv from an IPv6 connection""" return self.file.recv(len, flags) def recvfrom(self, len, flags = 0): """readfrom on an IPv6 connection""" return self.file.recvfrom(len, flags) def write(self, packet, flags = 0): """write to an IPv6 connection""" return self.file.sendall(packet, flags) def send(self, packet, flags = 0): """send to an IPv6 connection""" return self.file.send(packet, flags) def sendto(self, packet, addr, flags = 0): """sendto to an IPv6 connection""" return self.file.sendto(packet, flags, addr) def mcast(self, iface): """set IP6 connector into multicast mode""" # TODO: support Windows; use ctypes module in Python >2.5. import dl _libc = dl.open('libc.so') ifn = _libc.call('if_nametoindex', iface) self.sock.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_LOOP, 1) self.sock.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 5) self.sock.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_IF, ifn) class UDP6Connector(IP6Connector): """A connector for IPv6 UDP sockets """ def __init__(self, name = None): """initialize a UDPv6 connector""" try: self.file = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP) except: raise if (address is not None and port is not None): try: self.file.connect([address, port]) except: raise class TCP6Connector(IP6Connector): """A connector for IPv4 TCP sockets The TCP4Connector implements a IPv4 TCP connection """ def __init__(self, name = None): """initialize a TCPv6 connector""" try: self.file = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP) except: raise if (address is not None and port is not None): try: self.file.connect([address, port]) except: raise class SCTP6Connector(IP6Connector): """A connector for IPv6 SCTP sockets The SCTP implements a IPv4 TCP connection """ def __init__(self, name = None): """initialize a SCTP6Connector""" try: self.file = socket(AF_INET6, SOCK_STREAM, IPPROTO_SCTP) except: raise if (address is not None and port is not None): try: self.file.connect([address, port]) except: raise ### ### Convenience functions and adjuncts to certain probelmatic bits of Python ### network code. ### def inet_atol(string): """convert an ascii IPv4 address into a Long""" from socket import inet_aton value = 0 addr = inet_aton(string) for i in xrange(4): value += ord(addr[i]) << (3 - i) * 8 return value def inet_ltoa(l): """convert a long IPv4 address into a string""" value = "" for i in xrange(4): value = str(l & 0xFF) + "." + value l >>= 8 return value[:-1] def bsprintf(flags, fmt): """Return a formatted list of flag names. flags - the flag values to format fmt - a sequence of bit numbers and descriptions as a string Compatible with bprintf() from BSD's route(8) command sources. This can be used to emulate %b from BSD's kernel printf(9).""" assert isinstance(flags, int) and isinstance(fmt, str) s = "" i = 0 j = 0 fmtlen = len(fmt) while i < fmtlen: c = ord(fmt[i]) if c > 32: i += 1 else: for j in xrange(i+1, fmtlen): if ord(fmt[j]) <= 32: break if (flags & (1 << (c - 1))) != 0: if len(s) > 0: s += ',' s += fmt[i+1:j+1] i = j if len(s) > 0: s = '<' + s s += '>' return s pcs-0.6/Makefile0000664000175000017500000000072311256030610013416 0ustar andreasandreas# # Author: George V. Neville-Neil # # Makefile for building distributions of PCS. #PYTHON = python2.6 # #CYTHON = cython-2.6 # These versions are set for Mac OS Only PYTHON = python CYTHON = cython all: $(PYTHON) setup.py config $(PYTHON) setup.py build install: all $(PYTHON) setup.py install dist: $(PYTHON) setup.py sdist clean: $(PYTHON) setup.py clean rm -rf build dist MANIFEST \ pcs/pcap/pcap.c \ pcs/bpf/bpf.c \ pcs/clock/clock.c pcs-0.6/README0000664000175000017500000000014211255512624012642 0ustar andreasandreasPacket Construction Set George V. Neville-Neil Version 0.3 5 September 2006 http://pcs.sf.net pcs-0.6/PKG-INFO0000664000175000017500000000034511256035475013071 0ustar andreasandreasMetadata-Version: 1.0 Name: pcs Version: 0.6 Summary: Packet Construction Set Home-page: http://pcs.sf.net Author: George V. Neville-Neil Author-email: gnn@neville-neil.com License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN pcs-0.6/INSTALL0000664000175000017500000000136711255512624013025 0ustar andreasandreasInstallation Instructions for Packet Construction Set (PCS) PCS follows the normal Python conventions for building and installing and there is very little, if any, magic. To install the library and the associated packet classes into your system do: > python setup.py config > python setup.py install To test your installation do: > cd tests/ > python *.py Some tests fail if you do not have enough privileges to work with the Berkeley Packet Filter. If you wish to run those tests run them using sudo. To build the documentation you will need pdflatex and a BSD version of make(1) installed. Go into the docs directory and build the documentation: > cd docs/ > bsdmake all you will see PDF versions of the docs. pcs-0.6/setup.py0000664000175000017500000001313311256027412013475 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: setup.py,v 1.4 2006/09/05 07:36:27 gnn Exp $ # setup.py,v 1.14 2005/10/16 23:07:03 dugsong Exp $ # # Author: George V. Neville-Neil # # Description: The setup script for all of the Packet Construction Set # from distutils.core import setup from distutils.command import config, clean from distutils.extension import Extension from Cython.Distutils import build_ext import glob, os, sys class config_pcap(config.config): description = 'configure pcap paths' user_options = [ ('with-pcap=', None, 'path to pcap build or installation directory') ] def initialize_options(self): config.config.initialize_options(self) self.dump_source = 0 self.noisy = 1 self.with_pcap = None def _write_config_h(self, cfg): # XXX - write out config.h for pcap_ex.c d = {} if os.path.exists(os.path.join(cfg['include_dirs'][0], 'pcap-int.h')): d['HAVE_PCAP_INT_H'] = 1 buf = open(os.path.join(cfg['include_dirs'][0], 'pcap.h')).read() if buf.find('pcap_file(') != -1: d['HAVE_PCAP_FILE'] = 1 if buf.find('pcap_compile_nopcap(') != -1: d['HAVE_PCAP_COMPILE_NOPCAP'] = 1 if buf.find('pcap_setnonblock(') != -1: d['HAVE_PCAP_SETNONBLOCK'] = 1 f = open('pcs/pcap/config.h', 'w') for k, v in d.iteritems(): f.write('#define %s %s\n' % (k, v)) f.close() def _pcap_config(self, dirs=[ None ]): cfg = {} if not dirs[0]: dirs = [ '/usr', sys.prefix ] + glob.glob('/opt/libpcap*') + \ glob.glob('../libpcap*') + glob.glob('../wpdpack*') for d in dirs: for sd in ('include/pcap', 'include', ''): incdirs = [ os.path.join(d, sd) ] if os.path.exists(os.path.join(d, sd, 'pcap.h')): cfg['include_dirs'] = [ os.path.join(d, sd) ] for sd in ('lib', ''): for lib in (('pcap', 'libpcap.a'), ('pcap', 'libpcap.dylib'), ('wpcap', 'wpcap.lib')): if os.path.exists(os.path.join(d, sd, lib[1])): cfg['library_dirs'] = [ os.path.join(d, sd) ] cfg['libraries'] = [ lib[0] ] if lib[0] == 'wpcap': cfg['libraries'].append('iphlpapi') cfg['extra_compile_args'] = \ [ '-DWIN32', '-DWPCAP' ] print 'found', cfg self._write_config_h(cfg) return cfg raise "couldn't find pcap build or installation directory" def run(self): self._pcap_config([ self.with_pcap ]) # XXX The Pyrex Distutils extension is currently unable to propagate # dependencies on *.pxd files. If you change them you SHOULD rebuild from # scratch to be sure dependencies are not stale. pcap = Extension(name='pcs.pcap', sources=[ 'pcs/pcap/pcap.pyx', 'pcs/pcap/pcap_ex.c' ], include_dirs=['/usr/include/pcap', './pcs/bpf/', '.'], library_dirs=['/usr/lib'], libraries=['pcap'] ) bpf = Extension(name='bpf', sources=[ 'pcs/bpf/bpf.pyx' ], include_dirs=['/usr/include/pcap'], library_dirs=['/usr/lib'], libraries=['pcap'] ) clock = Extension(name='pcs.clock', sources=[ 'pcs/clock/clock.pyx' ], library_dirs=[], libraries=[], ) pcs_cmds = { 'config': config_pcap, 'build_ext':build_ext } setup(name='pcs', version='0.6', description='Packet Construction Set', author='George V. Neville-Neil', author_email='gnn@neville-neil.com', url='http://pcs.sf.net', packages = ['pcs', 'pcs.packets'], cmdclass=pcs_cmds, ext_modules = [ bpf, clock, pcap ], ) pcs-0.6/docs/0000775000175000017500000000000011323556365012723 5ustar andreasandreaspcs-0.6/docs/codespelunking.sty0000664000175000017500000000274011255512624016473 0ustar andreasandreas%% %% This is file `codespelunking.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% codespelunking.dtx (with options: `package') %% This is a stripped version fo the original file. \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{codespelunking} \newcommand\rtn{% \texttt} \newcommand\filertn{% \texttt} \newcommand\filelinertn{% \texttt} \newcommand\file{% \texttt} \newcommand\program{% \texttt} \newcommand\fullpath{% \texttt} \newenvironment{class}{% \textsc} {\textnormal} \newenvironment{object}{% \textsc} {\textnormal} \newenvironment{method}{% \textsf} {\textnormal} \newenvironment{function}{% \texttt} {\textnormal} \newenvironment{macro}{% \texttt} {\textnormal} \newenvironment{field}{% \texttt} {\textnormal} \newenvironment{constant}{% \texttt} {\textnormal} \newenvironment{variable}{% \texttt} {\textnormal} \newenvironment{struct}{% \texttt} {\textnormal} \newenvironment{parameter}{% \texttt} {\textnormal} \newenvironment{demo} {\begin{alltt}\begin{small}} {\end{small}\end{alltt}} \newcommand{\vuln}[6]{ %\begin{table}[h!] \begin{center} \begin{tabular}{|c|c|} \hline Title\\\hline Impact\\\hline Date\\\hline CVE\\\hline Affected\\\hline \end{tabular} %\caption{#1} \end{center}} %\end{table} \newcommand{\ucommand}[1]{ \textbf{\textcolor{magenta}{#1}}} %% This is the end of the stripped file. %% %% End of file `codespelunking.sty'. pcs-0.6/docs/design.tex0000664000175000017500000001020611255512624014707 0ustar andreasandreas\documentclass[11pt]{article} \usepackage{codespelunking} \usepackage{fancyvrb} \usepackage{listings} \usepackage[pdftex]{hyperref} \title{Design of the Packet Construction Set} \author{George V. Neville-Neil} \begin{document} \maketitle \tableofcontents \section{Introduction} This document covers various design decisions in PCS including how many of the underlying bits work. \section{Fields} \label{sec:fields} \subsection{Encoding and Decoding Fields} \label{sec:encoding_and_decoding_fields} In order for fields to be useful they must be encoded, that is the value of the field must be turned into a set of bytes, and decoded, whereby a set of bytes are turned into a usable value. The fields are treated as a list and their \method{encode} and \method{decode} methods are called by the \class{Packet} class so they must have a unified API and return value signature. When \program{PCS} wants to encode a value into a set of bits or bytes for use in a real packet the \method{encode} method is called. The API for \method{encode} is given in Figure~\ref{fig:encode_API}. \begin{figure} \begin{lstlisting} def encode(self, bytearray, value, byte, byteBR): \end{lstlisting} \caption{encode API} \label{fig:encode_API} \end{figure} The \parameter{bytearray} parameter is the real set of bytes that are part of the \object{Packet} object and which will be used when transmitting a packet on the wire. It is the \parameter{bytearray} that must be updated by the \method{encode} method. The \parameter{value} parameter is the value that is to be encoded. When processing a byte stream we must track two other values are we move through the values and encode them into the bytearray. The \parameter{byte} parameter is the current byte that is being encoded, or written to, and the \parameter{byteBR} is the number of Bits Remaining to encode in that byte. The return value of the \method{encode} method is a list of two elements as shown in Figure~\ref{fig:encode_return_value}. \begin{figure} \begin{lstlisting} return [byte, byteBR] \end{lstlisting} \caption{encode return value} \label{fig:encode_return_value} \end{figure} The \parameter{byte} we are encoding and the \parameter{byteBR} Bits Remaining to encode in that byte are both returned so they can be passed to the next field's \method{encode} method. The process of decoding a field requires three values be passed into the \method{decode} method and 3 values to be passed back out. The \method{decode} API, shown in Figure~\ref{fig:decode_API}, has 4 arguments, including the required \parameter{self} parameter. \begin{figure} \begin{lstlisting} def decode(self, bytes, curr, byteBR): \end{lstlisting} \caption{decode API} \label{fig:decode_API} \end{figure} The example given in~\ref{fig:decode_return_value} is from the \class{Field} class which handles the majority of the fields in packets. The \parameter{bytes} parameter is the buffer of raw bytes that we are processing. The \parameter{curr} parameter is the current \emph{byte position} in the \variable{bytes} array while the \parameter{byteBR} carries the number of Bits Remaining to process in this particular bytes. The \parameter{curr} and \parameter{byteBR} \emph{must} be updated by the \method{decode} method so that the next field knows where to start decoding its value from. All \method{decode} methods return a list: \begin{figure} \begin{lstlisting} return [real_value, curr, byteBR] \end{lstlisting} \caption{decode method return values} \label{fig:decode_return_value} \end{figure} The \parameter{real\_value} parameter contains the value that was extracted from the byte stream and which the caller, usually the \class{Packet} class's \method{decode} method is supposed to put into the \object{Packet} object. The \parameter{curr} is the updated value of the current byte that is to be processed in the byte strea, and the byteBR is the number of Bits Remaining to be processed in that byte. Both curr and ByteBR are necessary so that we can process values which cross byte boundaries. \section{Layout} \label{sec:layout} \section{Packet} \label{sec:packet} \section{Connectors} \label{sec:connectors} \end{document}pcs-0.6/docs/Web/0000775000175000017500000000000011323556463013437 5ustar andreasandreaspcs-0.6/docs/Web/pcap_info.py0000775000175000017500000000744511255512624015757 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: Walk through an entire pcap dump file and give out # information along the lines of netstat(1) on FreeBSD. import pcs from pcs.packets.udp import * from pcs.packets.tcp import * from pcs.packets.ipv4 import * from pcs.packets.ethernet import * from pcs.packets.arp import * from socket import inet_ntoa def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="tcpdump file to read from") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) srcmap = {} packets = 0 ip_cnt = 0 non_ip_cnt = 0 tcp_cnt = 0 udp_cnt = 0 icmp_cnt = 0 arp_cnt = 0 done = False while not done: ip = None try: packet = file.read() except: done = True packets += 1 ether = ethernet(packet[0:len(packet)]) if type(ether.data) == pcs.packets.ipv4.ipv4: ip_cnt += 1 ip = ether.data else: non_ip_cnt += 1 if type(ether.data) == pcs.packets.arp.arp: arp_cnt += 1 if ip != None: if type(ip.data) == pcs.packets.icmpv4.icmpv4: icmp_cnt += 1 if type(ip.data) == pcs.packets.udp.udp: udp_cnt += 1 if type(ip.data) == pcs.packets.tcp.tcp: tcp_cnt += 1 if ip.src in srcmap: srcmap[ip.src] += 1 else: srcmap[ip.src] = 1 print "%d packets in dumpfile" % packets print "%d unique source IPs" % len(srcmap) print "%d ARP packets" % arp_cnt print "%d IPv4 packets" % ip_cnt print "%d ICMPv4 packets" % icmp_cnt print "%d UDP packets" % udp_cnt print "%d TCP packets" % tcp_cnt print "Top 10 source addresses were" hit_list = sorted(srcmap.itervalues(), reverse = True) for i in range(1,10): for addr in srcmap.items(): if addr[1] == hit_list[i]: print "Address %s\t Count %s\t Percentage %f" % (inet_ntop(AF_INET, struct.pack('!L', addr[0])), addr[1], (float(addr[1]) / float(packets)) * float(100)) main() pcs-0.6/docs/Web/index.html0000664000175000017500000000423511255512624015433 0ustar andreasandreas
Packet Construction Set

Packet Construction Set

IPv4 Packet Format from RFC 791

IPv4 Packet Format from RFC 791

Overview

PCS is a set of Python modules and objects that make building network protocol code easier for the protocol developer. The core of the system is the pcs module itself which provides the necessary functionality to create classes that implement packets.

Download Now!

Developers

Everyone is welcome to download the latest code, though it is not guaranteed to work as this is a link to the live repository.

Mercurial Repo Access

Example Code

PCS comes complete with several different example applications including:
  • http_get.py is a simple command line program to grab a web page.
  • arpwhohas.py generates ARP queries given a set of IP and hardware addresses.
  • pcap_info.py prints the statistics on packets contained in a pcap dump file.
  • tcpslice.py will carve a set of packets out of a pcap dump file.
The scripts directory in the release contains the complete set of example code.

Documentation

Documentation is provided in by the PCS Manual and, automatically, via Doxygen.




SourceForge.net Logo
pcs-0.6/docs/Web/arpwhohas.py0000664000175000017500000000630011255512624015777 0ustar andreasandreas# Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: arpwhohas.py,v 1.1 2006/09/08 07:15:26 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A simple program to send ARP requests and replies. import sys sys.path.insert(0, "..") # Look locally first import pcs from pcs import * from pcs.packets.arp import * from pcs.packets.ethernet import * def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--interface", dest="interface", default=None, help="Network interface to send on.") parser.add_option("-t", "--target", dest="target", default=None, help="IPv4 target address to lookup.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="Ethernet source address to use.") parser.add_option("-p", "--ip_source", dest="ip_source", default=None, help="IPv4 source address to use.") (options, args) = parser.parse_args() arppkt = arp() arppkt.op = 1 arppkt.sha = ether_atob(options.ether_source) arppkt.spa = inet_atol(options.ip_source) arppkt.tha = "\x00\x00\x00\00\x00\x00" arppkt.tpa = inet_atol(options.target) ether = ethernet() ether.src = ether_atob(options.ether_source) ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 0x806 packet = Chain([ether, arppkt]) output = PcapConnector(options.interface) out = output.write(packet.bytes, len(packet.bytes)) reply = output.read() reply = output.read() packet = ethernet(reply) print packet print packet.data main() pcs-0.6/docs/Web/http_get.py0000664000175000017500000000363511255512624015631 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: http_get.py,v 1.1 2006/07/13 10:05:40 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This script uses PCS to send UDP echo packets (port 7) import sys sys.path.insert(0, "../") # Look locally first. import pcs from socket import * def main(): conn = pcs.TCP4Connector("127.0.0.1", 80) conn.write("GET / \n") result = conn.read(1024) print result main() pcs-0.6/docs/Web/Makefile0000664000175000017500000000040711255512624015073 0ustar andreasandreas# # # File: $Id: Makefile,v 1.2 2006/06/15 07:52:02 gnn Exp $ # # Author: George V. Neville-Neil # # Makefile for updating PCS web pages. FILES = *.html *.jpg *.py ../pcs.pdf html/ install:: scp -r ${FILES} gnn@shell.sourceforge.net:/home/groups/p/pc/pcs/htdocspcs-0.6/docs/Web/pcap_slice.py0000664000175000017500000000624611255512624016116 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: A program using PCS to analyze a tcpdump file and give # data relateing to whether or not the file shows a DDOS. import pcs from pcs.packets.ipv4 import * from socket import inet_ntoa import array def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--in", dest="infile", default=None, help="pcap file to read from") parser.add_option("-o", "--out", dest="outfile", default=None, help="pcap file to write to") parser.add_option("-f", "--first", dest="first", default=0, type=int, help="first packet to start at") parser.add_option("-l", "--last", dest="last", default=None, type=int, help="last packet to keep") (options, args) = parser.parse_args() infile = pcs.PcapConnector(options.infile) outfile = pcs.PcapDumpConnector(options.outfile, infile.dlink) first = options.first last = options.last done = False packets = 0 written = 0 while not done: try: packet = infile.read() except: done = True packets += 1 if packets < first: continue if packets >= last: done = True outfile.write(packet) written +=1 print "%d packets copied from %s to %s" % (written, options.infile, options.outfile) main() pcs-0.6/docs/Web/IPPacket.jpg0000664000175000017500000022211711255512624015601 0ustar andreasandreasÿØÿàJFIFÿíPhotoshop 3.08BIMÿâäICC_PROFILEÔapplmntrRGB XYZ Ö 8acspAPPLöÖÓ-applrXYZ,gXYZ@bXYZTwtpthchad|,rTRC¨gTRC¸bTRCÈvcgtØ0ndin8desc@ddscm¤Ömmod|(cprt¤-XYZ yz@vÒoµÝÊÕ¦»Óìôiµ‹‹¸×’‘ÙA’Ü7FˆÌO@kÂà“Þ8_þÈún7†Õ| á‹òµ¿Ä9|âÜk>Õþ i³Xx«^‚[+5ž{øî#Žà¢ÜÇ<5ÄQÉöx!(¨Ìè¥?iÍÑiëxhþNNýmeðÈ*Þ*«}ý=í~ô•µj÷z4}ER¢Š(¢Šù·þ å¬Þè?ðOïÏa{y¦é6—ˆníehdµÐ¤Ôí#ÕäóP‡‰WN{ÒÒ! Š”‚6⮿à|û.ï¢* JI7d}§jvÚŢϤÜAuÈ qÁTÿZøßöð'¾ ÿÁA~6ø7ö<Ò¼9 |1´ð—…µ;í'ÃqEc¯ÎúšÊÑÃ"Šâ]>--ä 2è-än\3ýûT|8°øµû>ø«@ñN·¯x{N¿±u¹½ÑµWÒïÉDºŒ‡Œ>6¤1Œæ–"~Æ›¨–Êözmÿ uÝYõ Qö“äo¶Úî“ýlüîŽúÚæ;Ûx泑%ŠUŽŒ]HÈ Ž#½G¨êvÚ=”—:½Ä¶ñ ¼³HœrÇÉóßüöïø%wìæÖsE0O†ÞF(á‚°Ó Êœt#Ò±à©~øžðGŒ?à ,š×†<®<Ú?ƒ®,¢Õm¼i«\ÚÍimf4©"s¨\~þF†$«üçåRFظ¬5IÁ;¤íë­´Zêú.¯Bpÿ¿QvÝ_ð¿–ßE©õ3%ÄK%»¬‘¸ ¬§!èAî*¾«­ÙhP,ºÝÝ­œNâ5yåXÕ˜ôPXŒ“é_8Á'~Üü(ý–ïtÍFÏDðêÜx§XÔ­¼!¥jQ_ÛøÚæé§‡E/ ´I$ȆH¢>\o#¬yŒ)<_ü·àçÿÚoân™á8tO‚¾/øí øCSÕ¼5¤|U°º¾ðõ®™<ÐÇsz`T14«qoh»ÇïcC&0®s•Yrrò«Ý^Ý~fºÞÉ;ÛK'+´Š¤¹Ü“z&Õú|\©ëk&íkëªM\û6¡¿Ômô«c6§<6ЂÉ+„PI ž9$îkçø$.¹»ÿÆøl¦¾º];ÂvzSÜ]]-Ùº’Ñ~ÊóGp ,ð;ÀÏ«ÃÄѰë_(ÿÁt¼Aâjz¯Äÿ‡õ„ 4«wK¹Ñá·’Ç_ñ$׈‘ÍvÆê6ið†+ +,³]ï+þ}+ÅQ«ìï¥Ú¿’»o¯E§FÚM«ÝaN£jÕŸ-í~¯¥ý^¯¢»¶‡éåVŸY³µ¸ònní£—±¥PÜôàœóT¼ â–ñ¿ƒtÍbM3SÑ›S¶K“c¨Æ‘ÝÚnòæTvPã8!Y‡¡5ù{û^èú?ÿڿöŠøý/†¿eïˆúÂßx}/txNk¯%ôZfžÂÏLÕ&Ûœ®²ÛIj±Ãt&žB›âlìQŒ¥V4’ÝëåªWûÚ_4kuÈå~šy¾ßußÈýXª÷µ¥¥ô·WVñ\ÝgÉ…ä $Ø;Tœ¶\Têw(<Œú×ã~£áMOPý©¼uñ§ö¢ÑþøÚï@ý£ôßišeå¥úxÿEµ]JÒÛH]7TKЖ¨‹qÿö|vÆ+¨då}Ó6ÕNÓ­MÚöüeY.­¹«l»´µ“TEÞÖÿ·e/ºÑwëªÑŸ²$àdÕiº¢ÄtÍBÆäNŒÅ:¿˜ÎWž=*쑉ceeX`Q_Ÿß²OüÃଟðS/øÇà÷Âïø7Gýœ-í¼áø´]ÖÒ{ÍjòÆÞþûQ»š4ón$ŽÒòÂÚ+1R÷Ë8e!ïMEí«o²_ðmç%{-E- Úßóþµ~‰Ÿ UZËY´Ô®.!Ó®­®&´m“¤r«´-èà©ö5ñÃÄ0xKà·‹õ]Têëk¦h—·s)7ß„Žfû2÷›ìÛùOÿŽø9{ð7ö•ý—µ_hŸ´4ñï­M,n¾ÆÃWñ3í³¸7ž(‘À7j Šö„.öyT¶Ù#ÝTcíe8좗â¦×þ×ÏÈ*µJš›{»[çþîeúŸ°_MÕí5˜]êÞî%s<2 0꤃ÔzWÿÁH|;?‹?`¯‹švŸâ='ÂR\ø^õ[VÕ54Û4ææî/žÞPÈò¨%‹qƒò—üÅSAÿ‚|_ðÿƒzÀ¿iðÿöφ•â íï¡ ¬1~î6‰¢Í$Hn›y¤bj MJWZinºr½»{Ú>é«uýÛyÿÁZwz]®‹Së‡q…U$œ)!™.aI-ÝdŽE ¬§!äGQ^=ÿøW¦|fý޾ è3Ö5ÝL¹Ñ.Þâ]'U}2yÕ`r`iã!¼·û®€ÊJž oö:¼‚÷öJø`ö F<'¥.!#bgÊàc¦;TS~ÓÚ/åäùósþ\Ÿˆª>GM77Ë—“óæü>ï@Õ5kMÍ®5««{;u 4³È#@IÀË1­N’,¨6 ¬29z×ÉŸðT¿ ü´‡À7ý»ì[ƶž»»Óü-ðúk+}Z߯šÅúG 1G¥NŒ·wˆÖ%R<Ò;*eÓ¤ÿ‚Pxóá—ì[£èúäú7k:Ì£CÑ5xõk$ºÌ±è1ÜÆJ·öz:Ù²®U@¨®dßoêÞ¶iù&¯kÆî^í­×þ¾š[Ï[^Ò·ÐÚž·e¢¬GY»µ´¸Ž34«˜Ç¢®O'ØUªø_þ ‰û>ü?ý¨þ#jºW†´O‚,øíáÍuieñbÞîïAÑôkÉgQ} ;ZÝgûU‚«\(ócDùˆWPþóÿÐñm·Ž¿àÿµmµÙ-o< £4Rk7 s¨J¢Ê%ßq2ü²»cqpÙÜÎ(¦¹á)=Ó_;¹­—.¾m®—eOrj+ªû´‹×ךëº×®žÓ}©[éq£êwÛ¤Ž±+Já;*‚z’x½M_–¿ðYÿø£ÄŸä¼øÇðËâ-çÂïƒÚ¯…5ÜiZÉcâÜkŸh¾‘Ül µ³}ŽÞ'P­-åË6BÆÉúwá}pøŸÃ:v¤öWºqÔ-£¹6—ˆ©qk½Cyrª³(uÎ FAÁ=jbù£Íý]}-Öé\áÈ×õÑ?Âézߥ›š]fÒ¯"k«dŸ!|¶•CäôÎyÈ«5ùOñ“BÐ<ûf|jøúþý˜þ#é~ø±áÝkø:i¼{§ß‹ ÇÉÓµYÊ­¼ÑÊbº·†+yÖbÌVhÙóêÅjtã4÷Iýé5¯]ÜL×,ÜOÏT×ɦŠòêÖj1YÏun—s©xài’@:•\äíV ÀɯÇ/„:-Ôÿ´Ü?¿hÍ7àÏ1ø=ð»À> Ñÿg {ox~-Eµ´žóZ¼±·¿¾Ônæ<Û‰#´¼°¶„ÊÌT½ãrÎ~²ý·|SeàØËâÞµâK¯ÙiúOƒ5{Ë«•u[x£²™žK2ÿ(¸U¡n…ÏYû:>ÖÚÙ»yt×ûÊÍy5ÖèÖ'Zº¤¶m+úï§“ÓÕ3ÑôýfÏVy×K»¶¹kg1L"•\Ä㪶Ê}Y¯Ëø%_Á™ÿg/ÛSáMŸ‹<5ðÂ×~2ø/w=¢ü‡É³ÖÌzcOw®oÁ¹`²Ú‹[…ßóM~ÎäÏÜ_ðRÏâÏØ+âæ§øIð”—>½VÕµMFM6ÆÍD¹¹»‹ç·…”2<ª EbÀ`눊¡Ó»\ß|dןkíש͆©õ„šNߊOKÛ½·éÐöM7W´Ö`it{«{¸•ÌlðÈ$Pê’QéSK*Ã<̨ˆ 31ÀP:’kó£þ b© ÿÁH>/øáGÁ½à_ƒ4øûgÃÔôÛÝ=u¦»Ô6\Jºi0Cs%¨SõÒ@-¤”)dE÷ø+Tú{þÎ>Óþ&ζßµÏøsKñ¼’Na´yõ‘â¹`1öif6ÐNª&”1ÚH#‹½4·›Qô¼ù.ü¾×øu+~ñïÊ›ÒúÚöWK_³þ%e¦§Óvðj–qÜi“Ãso0ݱ8tqêpEJî#BÒª£$“€|Ÿÿãðç…¾üxý£üû6ÛØéß 7JÒ¢Ž-CÔäÒ­¥Ô­,#‹ä…½¼²DUfžo”35zwüá^™ñ›ö:øƒ xÏX×tM2çD»{‰tUôÉçUɧŒ†òßîº7)*x$lMeB„«%{G›ð¿ÝÙõZõ:(RöµcNN×vümý~}Oa†d¹…$·u’92²œ†AEAªkš¯Ÿ­Ý[YÂX'™<«î=X“é\ìuyïì•ðÁìŒxOJ\BFÄ"Î/”ÀÇLv¯ ÿ‚øOàE¯ˆü âïÛ;@âv©eþ࿆·66š´>+ÔïZÙ·Á§\¡Gº‰mv —dŠÞ+‰ÚFU;—«ªÕ•;Þͯ^ŠÉ^í»$—VrajýfŒjµkÅ?M.õÓEÕ»h®ÈâªêzÝ–Š±fîÖÐNâ8ÌÒ¬~cй<Ÿa^ÿ¾øsyð“öðO‡uýSBÔ®tÇEÔÿ´´ý N¡rɤ[Ýdù©§«-€n?ãÓWGŠÿÁQ?g߇ÿµÄmWJðÖ‰ðCÅŸ¼#à9®­,¾,[ÝÝè:>y,ê/¡‡k[¬ÿj°Uk…lhŸ1 ê1?ìò’Z¥“z}ÚöWzÚÏj)UW½¶ôÕ¥äÖúivì­v}ÑPÞêVúw•ý£q |‚üÇ æ9諞¬pp5âßðMÛxëþ ßð;VÑÛ]’ÖóÀº3E&³p·:„ª,¢]÷/Ë+¶7 À â¾;ÿ‚•ø»ÄšÏíu¦x‹ãoÂÿ‰Z—‚>ø·Â1|?u•¥Î™ªjWÎ%ö¬åБal¥—æ]9cç+yRQÅ,=ôrå¿•í{yéeÝö»QFN­5;Yµ{u½¶ÿ?ó²¦uZ]fÒ¯"k«dŸ!|¶•CäôÎyȤÑu#¬èÖ—osfnáIŒ h7(;@aœ “_–?4-À?¶gƯ¯áÿÙâ>—áï‹Ñf±ñƒ¦›Çº}ø°Ñl|;UœªÛͦ+«xb·f,ÅfŸ1à­í9;uüb¿9/ùZ{7?»ÏFí÷&þLýXªï«ÚG©¥”—Vëy"V ²‚Ás’3Þ¬WãŸìiái,h¯‡¿?h-á¼[㟎þ(ðä7‹§ÞÚüEÐnâ—W³„˨›×[‹K{;o-´Ï³C Ví £/\޳Œ;Ù|ÛQKæß§{-Sšå¥*¿HÊOîQ}íw£ýŠ–T‚&’vTD™˜à(I=ª­ˆ´ýLÇý›gqç ÑùS«ùƒÊàóÇ4ísD´ñ.‰y§kÐ%ÕŽ¡Û\BÿvXÝJ²Ÿb |û Á>¾YÁA~$|IøQð§À~ Ó~ Kßãhö2=ÏØ`¹ÔõI¥ÜLÿmŠÉB̉m9 ›‡¢šs›D¯òZ==\WÏÈR´aÍÖöõo¢ó²“ô‰÷ÕVÓu‹Me$m"êÚíbs˜eY8ê§‚=+ſা%±ð‡ü³ãŽ¥âk¿iú}§µv¸ºðûÔíÙÊ –ÎØ "ƒ¸9 .7Í|ƒÿÀø5sû7ÿÁBìôOøsàGƒõ/ü‡P†ÇൡµÐuo}l·7z²8óoº‰l¦_bBâi·:Ê“Z;ëæ£9í–ùß çîCŸúø£ý»ð·SôÀœj¾™«ZëV‚}æÞîJ‰!H„ƒ‚28U}ZOïsKçî=;k}>®¸¸KX[§HâK»¹Â¨’Iè9H£!•†A Šùoþ ]ðúÃâ7ü¿ã­·ˆõÍwB·Óü¬jA´½Uôæ¼x,.$Ky2@ì <$í‘AVK)úàÝÜ7ß <1%„±MiV¡^6 §(àŽ)Aósù[ñ¿ù ~ë‡÷¹¿ò^_þHé(¢Š`õŒ¥”ÖÚœ1\Û\#E,R t•a•”ðA‚ZÃø­ñ*ËàÿÃíOľ#²ñ£e¥F²Km¢h÷ZÅü º®!³´ŽI¦9`HDb$𠯘?dŸø+“ñ×áGŒuïø3âÌ7>Öõ¸,>øŒ-Ŷ¹5…¢B¦ÕÌ÷‚³´ðFL‘ºÜŽ1ª )Þ>WùË$”—V’õþ¿Cé_ƒüû:x8xwö~ðw…¼ áñ;Ü7@Ò Óm<ׯù<˜SqÀËc'Ò­üPøQáoþ½ðÇÆŸ xÅþÔö}³IÖôèu ½Ž²'™ÊÈû]†AÃ(#+Æ-?à¥Þ Ô<«ë–¾ øû¾,I ÿüOÔ­0”¡†Ý¬“"ù-½ÑJǹ7Þ¹âdïø+ñö,ðÄŸ‰> ø´5{ý+Imb áWˆç†[Û»V™ßOm${›0ÑH<øÚXÔ4A¤Ì‰¹ÛI¾–¿ÏoëÍbãg?ó©ô‡ÁŸ€>ýœ|'&ƒû<ø+Â^Ц¹kÉ4ïèöú]£ÎʪҘmѹT@[!TgU>7þÌŸ ¿i­.ÆÇö‘ø{àˆ6Z\­=¿‰t+]Z+Img‰.cpŒG¨Ž+Ã>?ÿÁR´/‡¿²Œþ$xÁZ÷F´Ô"Óm5O…~"¾Û‹\Æ÷Vïi±Y“±ZåÌq˜©Æÿ…ÿà¥Ô¾hÞ6Õüñµ¢Ô.Â[[_„þ$’ð\}ž9šE³F³&ãi‰˜XRäª9)}ž[üþÉ~Êà£%ö¹­oîÚÿŸÎϱ쿾 ø3ö~ðd~ø á x#ÃÐÊóÇ¥è\m”r9˸‚T Ç’q“Þ²¾:~Ë ¿j >ÂÓö”øwàˆ6ºT5”^$ЭuD³v3D.#`„€+ŒÍ|õûWÿÁYô‚ÿ³Æãx'âô·º¾©eio§ð§Äh°DÚ­­É¹ŒÚÆÖîb¸Â$*ep¡„íoEñ/ü_Á¾ð‡‡µ»ÿüvž×ıÏ%´6Ÿ ÄÆ\­F=cunÎëúòk¹íÞðŽ“à iº4Í?DÑ4kXì¬4û d¶µ±‚5 0Å jªU@År&ý”>ø×ã&›ñÆ? üªü@Ñ•ÃÄך¬ú½’¦í‚+njʛw¾0Ûɯ›h¿ø,“ðgö†øIáMÀ¿/4¿\ÜfVøWâI.c·þÆ’þb«h<ùĆšY^&$f7)ê¿à£ økãYô-oÁ¿ïn­Öiô¯„ž%Ô¬ØKJ»nmì& HÄ£VÃ)ù')¯æ¿Îÿæ%Ëåøù\>¡û1ü7Õþ5ÚüJÕ~ø*çâ%Œe¶ñDº%³ë6ñmeØ—…<å]®ë€ÝŽ„×Ï_૚WÂïÛwÃÿ åðoÅk½m[—T¸´ø[â+Ù¥½´ºÓ"·{aµ)si²îïÍž5’5?g̉½Dž‘ÿð†ñuü7„>8>¦š¨ÑÍä_ |G&’e2ù^`ÔÇìÆß'wÚžVÏŸvÞj#ªŒãÖöùhÿ®Íw*qqMIzÿÁû¿Ýk3Ãþ Ñü'«Ýx_JÓ´ë¯^hê’Û[¤O¨Üù1AçÎÊ’O*#ÞÙ;bEÎò¯Ã?ø*î•ñöã×>'ƒ~+[hðèÚ,ºuÅÇÂßZÍõÕî§ÃÞË-¨ŽÞËe¥¡ŽâEŽ2~ÑûÇØÂ?BðüWÁßzžá⯠i~;ðΡ¢xßM°Ötm^ÚK;ë ët¸µ½‚E+$RÄଈÊJ•`A‚+à×À~Ξ _~Ïþð¿ü>“=Âéš—h%|o*UÜØldàWËß²üßKø÷â/Œ6Þ)ð7Å{;‡þ"¼µÓM¿Âÿ,—|vRíZÕˆ¿2\Í‹\$ÅfôïÁFüâ ëúŃ><ÁmáÈà–â+¯„^&·º¸L±(µ·’ÀKtÁ˜3,*å`*Ö³þhÆ_&®¯þ]Én÷Oì¶¾kGo_ÊǺkš—‰ô[½7Ä–vº†¨Bö×V·1,°ÜÄêUã‘ue$ ‚ °¾üðoìûà{ |ð§†üáËGyaÒô-6>Î'v,ì°Âª€³IÆI95ò÷ìQÿnÓh¯Ù{TñßÄO|S´¿Ðïïa»·Ò¾x‚T¸…u{‹+o± ¶‘®åEN—h[Ìó=¬«èÖŸðR/j?uÚø3ãÄvº5ͽ¤¶óü"ñ4W²¼ë+#CjÖY£_!·É²ÆZ0å|ÄÝ2^ÍJvÙké}?§›*)Íò®ŸÓ=wâ×Áü}ðTþøëá? x××N’Í¥kÚd•”ÎŒ «A#‚2)¿¾ ø3ö~ðd~ø á x#ÃÐÊóÇ¥è\m”r9˸‚T Ç’q“Þ¾cý•?à­š/ÅÏØÛÁ?þ%ø+âÿöέ¥ém«Ã¡ü'ñ%ųÞÝZ4îö–’µÅ˜h¤xÚXÆè™u¯Ú§þ µ£ü#ýмgñ+ῃ~-[MÒõs£Ûë_ üGQßZY‰ã}B´ŽK{"ÒF ÄD, H o·IÁÑsO¦ÿ…¾ý-ò ëJ1[ôüàþ'½|rý”~þÓɦ¯í+ð×À×F2ø§¨iþ)¿º‹\ž†>!»BºD—Ðg46Ûn¥y+*D&h”K½c(̵ê—}}VŸC7k¦÷·á¹ôN«û(|-×~6Ú|KÖþøóâ-‚„¶ñDú¬šÍ¸ P½hüå³(ÃpŽ„×^ ¯ÿÁD<áψ«á‹Ï|sšù§†Ü\Úü'ñÆŸºP…I¼ŽÄÀo›~† AS1ñü«NÑ?à¡ZwÂðOÅ)49´ù®oSá—ˆs¨Ã©ÚÙÆÐÈ-¶I§”šfkÅV€,ùÀ0 éÅÎP¥··m“üÍ´ºŠRIJo¥¯óv_×dÏ£ãý™~Cñµþ%Ãà§ÄY-þÊþ(%°ÖZ-»<³{³Î+´ÆìméÅwáVðP^ü^_Gá驾¯ýŒ/døSâ4ÒD¾w•æDØý˜[îù¾Ðdò¶|û¶ó^oðÏþ »¥|Cý¸õφ àߊÖÚ<:6‹.qqð·ÄV³E}u{©Áp÷²Ëj#·²Ùihc¸‘cŒŸ´~ñö0B<Ê*;;Ûóvûÿ2äšR›ékýö_×eä}Uáÿèþ¿Õî¼/¥iÚu׈/?´uIm­Ò'Ôn|˜ óçeÉ'•ïl±"ç Òt!Yea‚È"¾~ðŸü—Á~2ñ9Òtß||¶¸\Mæß| ñ5¶!‰åaçM§ªneŒª.rîUeý™ÿà¬zGÇ‹ß4 [ÁŸmlü«2hïÿ ¯ÄvÒ(´;+ùRôËjDw4×B+r#’T6Á#s"4‰~ò벿ÉY~ ð^ErI=µ½¾ðçÐ?e…ß³–¯¬ê³ïÃøÿÄNU¹ðþk¦Ë©2–e3¼©—ÜÄà³æ»xSKñ߆u Æúm†³£jöÒYßX_[¥Å­ì)Y"–'dFRT«$^!à¯ø(çƒ|y´ÚOƒ>À”’ö«ù’ó»M¯Ë~íw>Žø5ð#Á³§‚×ß³ÿƒü/à¤Ïpºf¥Á§Z _ßÊUw6[8·âßé^>𾣡øïLÓõ­W·{;í>þÙ.mo`u*ñK‚²#) «$^¢ÿÁIü®øcYÕ­<ñö+} @gŠãàÿ‰á¹›Í“Ë_³Àúx’ã–«l_™°9®#ö@ÿ‚«é_ÿc½/â/Ä?|VƒT‚ÂÆm^ÛLø_âI¦¹.£û:!k#ÞĦ3½ài–0T³Ã.MJê_×AB.+š=ã¹ô¿Â„øàK/ üðLJüá­;y´ÒtM> +bî]ÊA ª)gfb@嘓É4ß‹_<ñ÷ÁSøk㯄ü5ã_]:K6•¯ijVS:0df‚tdb¬ŽȯñÏüÛÂÚìûâè~ øÛ·Iim!µ¼øOâHn^à[K:;Û5’Ê-¿uµî0"BB³©"°ÿfÿø*¦‰ñCö2ðGÄ߈ ø¿þ¹c¦¦§g¤|-ñÖ/n,VæG´†;I$šÈ6õ[¤2DrƒÌbÃ4Ó©Ï)}ž[ßû×·åòºîˆº-ºó[åkþƒì}ð‹àŸƒ?gïGáÏ€ÞðÇ‚<= ¯e¯ßþO±j. ÑÓOÃüµ_yï¶vpéö‘[ØE@‚8ãB¤j¨\oÆïÙ§áÇí3£Yi¿´‡ÃÿüAÓ´ÙÍ¥¯‰t;]ZYJ•2F—1º£$nWÏ_µ'ügJøâO„Öš‚þ,]ÁãÍ^Ìj¾øŠåàÓî,o'Ä"µ¿[ÂÔ†™ÈZ ²ö¾.ÿ‚–ø'Áz…½¶¥àŸÚéîl­¯Õ¬~øžò5IáI‘âÓÙVUY¼d‡Ã#…ee¦ª&û;|ÕŸë÷§Ø\-n±æÓ³n?§Ü×sè+;8´ûH­ì"Ž AqÆ¡R5T®Uý”>ë¿m>%ë üyñÁB[x¢}ÖMfÜ(^´~ráY”a¸ GBkÁ><ÿÁV4¯‚ß¶…>ËàÏ‹ÚUö«O«\Ù|-ñ¡$“@¶-oö -íJ\Ç‹©¼×eT*š2FïGñ‡ü Â> ø«/ƒõ?ümºÔa»ŽÌÝØ|,ñî–]öá–þ·hÆñºA!UÃdŒTeÏ$Öý?¯˜¥gv·áý#Üë†Ò?f†¾øÕñ'Aø}à›/ˆš¬?g½ñD´zÍÜ{UJIx±‰vÇÁcÂ(è>qñü«NÑ?à¡ZwÂðOÅ)49´ù®oSá—ˆs¨Ã©ÚÙÆÐÈ-¶I§”šfkÅV€,ùÀ0 êžÿ‚øGÅŸ£ð~ŸáÖúŒ—’X‹»Ï…~"µÒá`\ßËb¶â3°âO3cd`œŒ‘Ö0¨¾Õíòn/ñ_sO¨¤ù\¢úZÿ5uýwO±îu›áïé>}A¼+¦Xi­«^>¡zmmÒ#yráCÍ.Ð7ÈÁ9$(çŠù+özÿ‚¶i¿ÿmü4 ø§§èúVŸ£M£]^|2ñ „ë5Ò^½Ïö‹OlÒ -¡<«ÈLZL¾àø)‚þ#ø€éº7ƒ>=YN-no<ÍSቴû}°@ó2ùÓØ*yŒ±²¤yÝ#•D ìª_-×oÃwòÒïÓÈVæj=n¾ý—çøØ÷Û«hïm¤†ö4𔤑º†WR0A‚í\/ÀïÙ[á‡ìǧìÝðëÀ¿ÓZ‘eÔÚ®–/]sµ¥ñ®ò763œdã­|ïû:ÿÁ[ôoŒ_>-èºß‚¾/[Øø+V)¤4 üI Íe‡e*^o´;/i®„P’¡¶Ù¤ô_ ÿÁH<ã3]»Ó¼ñêÚ?XhÜ%÷Â/YÉq[-’[k™wL­äÄö+¾Ý¨å_+޽ã–ÿ…µô}Šk™òï¯ãþzþ'¶xßÀú/ÄÏj^ø¤i~ Ðu›w´Ô4ÝJÕ.­/¡q‡Šhd$F‚¬"³>üðwìýà{ |ð§†üáËGy!Ò´-6>Î'v,ì°Âª™‰$ã$œšù›öIÿ‚±é?~xÇ^ñ¯ƒ>,ÃsáMo[’Ãá_ˆÂÜXÛk“XZ$*m\Ïx!û;OdÉ­Áhã:§¡h_ðQ¿ø‡ÁZî½gàÏZxyí’â Ÿ„~%‚öàÎìŠm­^ÀKr¡.bVòÁRØ 32÷5}WáÓñüAÅݧѵó[ÿ]hñ×€ô?ŠÔ¼=ñ+FÒ¼C k05­þ›©ZGwg{ 4sC )"ÕXj/‡? |;ð{Á:w†¾è:7†<9¤GäØézM”vvvi’vÅ J¨ƒ$œ9$×Êÿ²wü³GøÇû"ø{Çÿ|ñ‚=Z{[!ª[èÿ üI1ü ð?íáøG¿høSÇZ.¿³ÆÔ»´åÁ ª&çws€2ÌIäšñO ÿÁJ<+©|Ѽm«ø;ãkE¨\%„¶¶¿ üI%à¸û*]kÆò]×Yøcâx"šÝâSý¢­mYDÞh(ó´K&c§¸8JPë}¯K|ŽxÏÚÆ2ïµÿ¯_ÄûŠä>|iÓ~?|?ƒÄžÓøŸÇ#\ÒP‚çOÒ¼A©Æ–b y­Ø²ÙÚ¤Q¶üå¶òI2ß*r{%¯¥×ü?ÈÒ0”ÒK«KæÔ­ù5ó>Ò‘ˆÊã!†¬_†Ÿ4Oƒßô/ ü5°Jð÷†¬ ÒôË(Ù™--¡AQ†rX…EQ’Iã’kå-#þ 'àŸ‹0ÿÁEm´ïØgÅ¿¼á¿hRèßÚö cÂS^KáË›p³]j6Î’5¤olåŒre—nÓóS/Ý©I­·ùwôæ^œÚÚãW›Œ{íó¾Þ¼mùzØúâ'ÃâÇ…¤Ñ>!XG©érÜ[Ý5»³(2ÛÏÄ/• å%†7õQž8­ºñÏ?¶¯†¾Yx:×SÓñ/üÓá–•yàx|¡üMñ‹|GÐîµÿ—7böG yä)·žØ²‰¢œFQ˜!ùÈB§(ÓmI¥ggò×òOî´Šqꮿøп¾øâ½–™mñK·Õ`ѵ[MnÉ&Î-ïme[̸#æIXgŽ9·ëæ?Ú·ö¦ŸVýþø÷öjñÐèŸü{àĆö(:Ž‘©_Ûï’d%°K´ð®»Ž ‘ÇÓ•¯$£ ]ZÓ”ZþòŒvô”W}-²Bm7;Þ)¯Fä—â›ù˜(ø[áÿxÃÃ^ ñN—o{¬ø:â{­éó¿O–hÞVLe¡–D9†õæ·è¯˜><ø×ã¶ûpøÁß üyðËJðWì5Qmµ/Þj•Œzp°DnÓX†9 íy!WòÊ  ¬¼šÍÉ&“êR‹’vè µ†º­ñIñv£§Ç/ˆô->ïJ°½.Ûíí®ä¶’â0 í!ÞÊÔ’A#Ê#';µù¡ñ‡þ ñÁþ-ü<³ø«ðCHñׇþ.øsÁ>Ðo¼!y=õÞ“ª?}ı®¬†y#Âéå©þÌŸ*<ñä}CûüføñWãÏí£ünÖü¨h? ¼džСÑü=q§]ßM²Ô„·3K}:ÊÁ5(¡ÂG&“þZHAÔ‚”~_åî?¾õ#uÝ»ìÅ7Ë£wÖß‹_ûkûq±øk¡éŸuOØéñÇâMgN´Ò/oƒ±yímd¹–Þ"¤íöé朓Ú(¨îîÿ®Ÿ‘‰áχ'„|SâoÖÚêž+¸†ëV¸VboeŠ·Ø@+Q§Ê 3Ï5·_:h¾$xŸÇ?µ6“ð¢ÿKÔ|KáK«K_Ù뀮—ew'‡¬î"Žs ‰<†»˜»œ³áÛi<³áÇ?ÚŠÏãWŽ¿ágë¿ Å-‚ÇGá¿ø*¿ÂCÂ^)Ö‹Ãÿ ô»}F‚âæê;X3±e¸žK‰›æ$åæšW<õcŒ+zD#+Œ†"¼Ÿölý±¼9ûLkþ#ÐôÆ>ñW„ã´¹Õ4hï¦êö×k#ZÜ…%’H¥ò'‘Ø«C"8GR£{öý£¼/û*|)»ñ‡Å©µÓ ¸¶±·¶Ó¬&Ô/õ;Ë™’ kKKXU¤žyf’8ÑKdàCœùdµvÓ½ö^wíÔpýã÷5:†Ÿ4Oƒßô/ ü5°Jð÷†¬ ÒôË(Ù™--¡AQ†rX…EQ’Iã’i~$|;Ñ~/|<×|)ñÂ=SÃÞ&ÓçÒµ;7vE»¶ž6ŽXË! #²äyàŠù+ö¬ÿ‚½Xü-ýˆ¾)üDø'à?ê¾5øt×Mÿ†õOË Ï‡5?³Ç4ªCæ!ûIà—Ï‚GI#cå¹==ûö8ñG޼gðLÔhÉ"—ÅÜ\‰Y<57‡ijºÄ_Ošêå¡mФþùÃd0À8ªjR»—ü=õüšwÙ¡¾j|²êÛõVü¿Ìôø![hR8TB¨€è+â'ÃâÇ…¤Ñ>!XG©érÜ[Ý5»³(2ÛÏÄ/• å%†7õQž8¯›ÿ঵—Œf]CÀþ ñ'†>xOÄ/¨6¿ñÄž¼ñ•á÷‚8šÚÖxmnmÅ¿Ú|Éȹže‰³. È˜Ïøÿ½ðÿìÇðÊÿö“‚ÓÇŸþ#6­>™¥ü,´]bÛ]²´»” FË˹–8ìþÌÖndšpC\GbVò«>hÊ2“{4¾o_êþ»j.WO•.×_#ëºÄñÃâî…sã ï§ðΤº¾˜ì̦Òíb–*í#'ËžeÁÈÞ+çoÿÁ^>ørÏáåÖŸ¤|L×­>+Bá›Hðåßöµâ‰KéûwÃuÙæóeb±‘”+'ˆ¿à¬~ðe–©q㟠|[ÐSFðÿï§àû›6‡JãKŒ‰p|øšUßÞÈ ‘{Ûkg÷8§/½$åä•Áj´Ù¯Â^ïÜÛ·ì}AX(ø[áÿxÃÃ^ ñN—o{¬ø:â{­éó¿O–hÞVLe¡–D9†õæ¼SǶܚł%†âŸ Y|OÔ9$×|+9Iĺ}ýÂiþrL¢ÊõM •„ªëåÆëÎÑøýÿ ð‡ÀO‰÷þ_|Gñ¿ˆt-"]¶ð‡†n5ì ¤xášé“t Å ŒÉ;,Nâ2ªZªÎïɵóJïî[ýû {Ûk¢&ì¾÷§á¹ï5?ÂßÜüR¶ñ¬ú]»xªÏJ—D‡Q9óc²–Xæ’Î6´DÝ3”õ¯ñ¯üç᯾2j^Ô-¼iw‡õ­;ÃZïˆìü=q6 jº„ZXÝ^+›«PÛ¬&â!3FXUÍs⯈í¿à¨ðE¾­:xJ÷á~­®O¦ãò彋UÓaŽrÛw†Xç™ r ‡N.u £»æ³ô§)¿¾ NêK£¸æ¹a'-—-þrŠ_‹OåÝ÷XV? t=3âN©âû>8üI¬éÖšEíðv/=­¬—2ÛÄT #ÞÝ0 |Ó’p1»EH¯£_×Ì+ Ÿ t?øƒÄº¯…4øìõj ªë+³딵‚Ñd`Ä€D–ñáp18É$îÑFß×õر< ðãDøge¨[xÂ=: WRºÕMws+M<§q8/#³02x¶è¢Úß®ß×ܾà½ÕºoóÕ_ñ{µ‰ðßáÆ‰ð‡ÀšW†>XG¥èZ%ºÚØÚFÌÉoôPX’@÷&¶è¢ÝBý ºÞ‹kâMóN×!K›+øÚâû²ÆêU”ûHüjŸ€ü¤ü1ð>á¿XŦh~±ƒMÓ¬âÎË[xcXârI¢¨$ñZÕó§ücÇß~ü-ŸÅ²-ÿÃ}/Hð–…­kÞ&¸ñF•uªM(´³óímí-íî­Çï]%W‘äýØÚB?"¢¥EF›Ûwè¯÷ÚîÝuvÕšR¥,DãN;½«·çeø\öÏŠ_ ¼?ñ¯áî­áOŠš]¾µáÝvÜÚßØÏ»Ë¹ˆà•m¤p:[à``WÊ> ý­~ þÎÞ±_Û^m#â‰é|ßC*oÚÇž;r¹Û©]¿¹m¿•Ϥþ!ü5Ðþ+ø~+⟧§Á¨Yj±Ã#²…¹³ºŠîÚL©1Ïo €t% Œƒ»^ñ¯öðÑþxCúϋ|ñbò {K¸Ö®"Ó¼2÷è6¶â#1¿ùÂÅ . Vy_kìGÚk‰ý¨ÿjøR‚ß¿gøQøUñÄ~ÑgÓoü1u6¡¨[j÷‘ÇöËm@_D°"xŠÅ%¤‡r’[ªB.r8õ”cä¥'ʯêÕ¯äû;IEɽ¢åꢓvôM7껫ýã‡'Ä Ý çÆßOáIu}1Ù™M¥ÚÅ,"UÚFO—<˃‘‡ |PÖ|5â8<_¨Cá+‹Okºf‡5Þá¯vhõ ¥á–h]‚ <¨åŽI|´`ÇÁVþAñËXð± |KÓux¢ÇÁú¶¥wáyãÒtÛûö‰tõ’ïîº7þ[.ì £.:’¡iµjÛ²ówKóiyݯ~›ù-_èÏ{Ÿáo‡î~)[xÖ}.ݼUg¥K¢C¨œù±ÙK,sIçZH"n™ÊzÖý|·ñWþ ßðçá‡Äù¼)e៊Þ.¾Äoá¹ðß„®5 ;^+µ\XÃ0À’XmÄ’¸\ŒE*©w²×übÿöªø¿ñ/Á6? ~!ø>çÁþ!“Ãöz¾«¢3YDF“i|²_1|—-t@„1܆Þ¾fF|ñJ¤›Ví£Ó¦¼éùó_­ÂVŒŸ3³ºOñZõÓ•¯.[t±ô.‰ð·Ãþø‡¯x³CÒíí¼Eâ{{K]Rùsæ^Åkæý_'O´MŒ÷ÎsÅo×È_ðOÏø)TŸ´¶>øé¦ëPü@]kĺ ×-<)u¥øg^¸Ñµ)í¥2Ë4ß7‘2•ó]wy¨®ÍŠŸ^Ö³‹‹Þþ}×uåØIÞýÌ/ |5Ðüâê¾Óã³Ô¾,ø·á.­>…âM@–ëNÔ!Ž9$´”ÕdVBFOÞR=ªîå-^¬˜E+Eh{ÐRFwF¤õ"–¤KTä?²¯ìùð—à·‰¼-ñ@i—¿Ûþ.ñV²Ék#K ÙêšÝýì(åÑNÿ"î5uÁ·ÌcëÕÏ|3ø© üaðýÖ©ðîøê6Z¦¡¢Í!‚Hv]ØÞMeuÙIÙqo2nkmÜ¥”‚G8Ê-]5gè_4’V}SùÙÛðoúGÆþÿ‚xs@ÿ‚fÉû!OÿÂO©éQ]µÝݵÜrØ¥íËËÜÛÛZYÉ ¶Xb yy]‘i¿ðG¿øGöQñ÷ï…ž8øAà량ڬ7Zïö'Áø,4¬¢b¶še¶£Ý£Y{›«’wHªˆ¥B}Úî#BÏÀQ“X >(è_þxwÆ oN¥á¿é¶ú¾—va’sk¯uuä|½âOØWâ–©Ã_è?|1¥üdøq¥j^OGà7“CÕt›Ö¶i-çÒR2¬ˆÖR,ÑÞ/ÏeJ9޹+þ ãï†>%ð×ÀŒZ…Ÿü!¯ø}‰< úÍö­­ÝG{¨jsO¥jˆ^îÚÞE!UUó6L_X|Oø¥¡|ð|šÿÄ{Ó§éQ]ZÙ´Â &Ä·71[@»#Vošiâ\ãvN$tä”ù“ë{üÓOvîõÔ˜/d“Ž–Ñ~–‰uKE¦‡ÈúGüÛÅþý†¾ü!ÿ„¿AñF¡ðgľ¼—Ym.M+ý7G½Š@«l%¹+?Ù¡DæM¯ -û°ÛWëŠæ¾'|_ðïÁ½?I»ø“©.™¹¬Yh,a’O>öòe‚Þ"’7È껎g$Ítµ£©)ÆMêœÜ›þóŒü]¼ïÔžU—h¤½/&¿%ò·@¯›þ6~ÊŸ¾!þØø“ðóâß<= x>ÖîÂÃ@½ø{q¨Ü½½à³ûX–ùuˆC9k ceDbBeÀ5í~/ø¿áßøãÂ~ñf¤¶š×Žn®,ôKc Žo¥‚ÚK©T2©TÛ 2>\¨;p2H¥¨¶ª]‹R²iuÓúíò>-ñ×ü;â‰âêøoãOƒôåøñCDø“mö‡s\émda²|jéöߨúPiuþ®ã ûåòGÿ‚wü{Ó|uñJóÀŸ´g…¼7£|Xñ­¿‹µ$ÓþÜG«X¤1Ø[‹Kkñ­í@öºd¼2JÁWpUúÇTø© èßô_êWÆ?ø‡L¾Ö,-<‰žÖÎKX®dóì]h6³o3*V+ÐÕFN 6Ù+/EÊ­çü8¯Xë­îM¹ïÞýµw×ñÕ‚Šç´ïŠš«ñWWðM…ñhZ]–µ}gäH6—’ÝCo'˜Wco’ÂìmV,¾^XÊ[¡©ÑÙÿ]#Ë> üÖ>|zøËâm~M=ôßëZv¡¥¬»Ì‘A¤ÙÙ¸JæÛH@Rà©SIQÁü.øKãØïVý ~&üTñ4_tï^?Œmü9á_Ig«Àöºl‹in_P˜^Ë%¶hŠ»aÝ6ó$žßá_ŠZ|aâ}ÃW¦çUðmÔz¼>D‰öIf¶Žæ5ÞÊó Ñ6P°°pA ©ŠåMÁÛF¾û?Í&håªçZi¦×·Ÿ™ù¦ü >ÿ‚e~Ø;Ðü)ñ'þ/MŽ»¦xÃw>¾¹×ì4‰ã»[ ¦Ã \A êZž©s:& Ôó6*ž—¥ÿÁ-›öâø «]~ÚßõIãZøSA<ÞŸB±[›{áqu§^<¯-ûÝYÙÉ/ž‘ÆE¸Œ[Æ­ ³þü_ðïÅ]CÄö¾Ô—P¸ðv°ú°¢#ûêC í . >#¹…·.WçÆr-i²M,lîïËÈÒwï(ɾekóy™©5e¦’“vV÷œ¢Ú·h¸«EÞÖ×cæø'ü¢?ØgUñ†§suðɯü[…¤–Þøqià­28íåe’§¸–{‰æBÎóyj,qGóôÏÛök“ö¥øE…¢x’÷ÁÞ Ñõ?Äz·mn·?ÙºÊ\Û¼¶ìÊ·—d–]ñ»¨d$2õ¿ >/øwã¯áñ'­Ium{«»8îV" -­Ì¶³®Ù[åš S8ÁÛ‘A=#¸ ?FM)ÍÝJOXÙ§µœ]Óò³WRWK®ž·Vkæ´>%ø»ÿ´ø•ñköuø«á«ïÞƒÇ?¯ÒoøŽO<ÖbÎ+Xím¬ô½8j‰ö1pÆL’ÏrÎÍ+¼¡>¹øQ£øŸ@ø}¦Ùüf×4øša}©iZCé6wM½Š˜í$¹¸h€BªA™òTœŒà;áGÅ ãÃøÏáéÔ¼7â½6ßWÒîÌ2@nmgeŠO.UWMÈêv²†ÁÒüTø¢|øcâ/|K¼:w‡<'¦\ë¥Ø†I͵­¼M,²yq«;íDcµT±Æ'Š©9FñÕ•¾^}Þ¯R¬æÒÝÿŸõ§m‘åµ/ìóñKâgÅ¿øÇöcø³eðöçÂZ•øz]sGñ¼kB†êÚ;ëS˜~Ë!GW § zIóÏÄø!f…ñáÇÃÁ«ëÞ ñŽü ©øƒVžëÅÞ¶×¼/¬K®Þ›íB6ÐÞá ¼kq±­Ì7+$!6´’‡“ÞðL·0¤É"†SŒdE`üOø¥¡|ð|šÿÄ{Ó§éQ]ZÙ´Â &Ä·71[@»#Vošiâ\ãvN$gegý|ûw[“­¯õ§«×Gºè|• Á1~%|,¶ø3gð#â×Ã}Lø9 ìÖv×ß U¸¾¾ûJÝÍ v:¥œ6ùwL‘B‘Œ¾Y‹õOÛwö ·ý²¼GðóQ>'¸ð»øGS+¬¤:|wCŲA5î‰)vT73XØ3È»Ž +‚ãèçüsñKBøm¨xrׯw¦Îj«¢iJ ’Oµ]´3N#Ê) û»i›sa~\g$r›””¥¿5þmíçw§.Îöµˆ4¢ÒZYßÑ'wåe­÷V½ô¹á?¶Ÿì…ñcö’ø³ðï^ø;ñ_Á>Ò~køOÓõOO®Í>¢-/lÙ¥¸MZÔ 0ÁÐ7˜AÚâÿìSñUøÏâ~ÌŸ¢ømqñJ²Òü_ž‹X3Éj#¿ÒÚK˜Åç“#ÄZe»ˆ„„˜‰Œïú^¹¯ü_ðï€üqá? ø³R[MkÇ7Wz%±†G7ÒÁm%ÔªTªm†.T¸$ 6V]ïóµ¿/ÉvEIÝ©>Šß+ßóoï}Ùñ¯ÅÏø!LJ>"~ÖÿÄ}Vð$vþ2ñŸâmeõ߇v½âK;«U·VM#Y¸oô(g[H÷¤–÷Išq³èí[ö~Öo¿oÝâ¤7:pðþ—à G²À]þÖ×WÒ:®Ý¾XKI;³’¼IÃ\ÕÏÅÿÚ|`³ðƤ«âÛý}~ &B^Ê¡‚I¼Í»$¸…v–Üwd"é7 SPÞ<Ö^´åòP¾¿FLÒjr—^[¿I&¾ù[]Ýìt´Q\öñSAÕ~*êþ °¾/âm K²Ö¯¬ü‰†Òò[¨mäó ìmòX]ªÅ—ËËKNåt¿õÛó:(®{Á¿4ˆ%ñ^á+ãu¨ø#SGÖ¢0IØîžÎÚõcÜêLÛÞÛ>ä,¿¼ÛÊÀ ]¿¯ê膊+ŸøuñKBø±§êW^½7Ði­æ‰vÆ "ò®í&h.#ÄŠ m‘w ©ÆA#š/wn»ü´WüWÞ†ÓK›¥íóÕÛÖÉ¿“ìtQ\ÿ¯ŠZÆÏ‡:7‹~ÞK@ñªÞX]$‡Ï‰¾ël‘U×>Œ¢ýÎ×: óŸÚïàιûE~Ìž8ðÿXxCTñž‘>Š5{Í!µh¬¡¸SÍöU¸ƒÌsȪ|Àб£wzþ»iá} ÷Sצö:t]\JT°Ž4RÌØ“€ ÀÕ‡´‹4ü=¼Žâm:ßUÓn„o¹¶ž5–)68 »‘Ôá€#8 ™ÓU£(µu¢;Úþ¶vïgÙ•N¬¨N3‹´“ºù[òºûÑà¾8ý‹~ xÂ_ uŸ |QÐtoŒ? ­n´ø 퀊fÕ/6ÇÑùY Áo >0ü^ðïÀ?†:ߌ¾-j+¤xoö­y¨^42L-â\e¶F¬íÔpªMt€ädw«›snRë%/šwVí­–—Õ£8Zœ8쓼šiúèÚ¾ö{ŸþÑßðHoö‹Ð¾ÿÂÀø“á¿ë~ ðýÏñÀPø³MÕ¦»–dÔíô细+KèÌL‘HLÊ‘Hc*Ó‰¿à™Ÿõ?Ù»àçÃ=ã4¿ƒÓèwv·—? ®.®µ9ôk…’ɦ#]EU1Cl’¨’GVŒ8DûâwÅMà熠Ö>#_?N¹Ôì4xåI6ë«ëÈl­cÛ³ ÷0¦â6®íÌUA#¡§ JÃEÌ¥åÍäŸk§+®×ìSnJϳ_&¬×Í+3+À¶Ö—àÍ*Ûâ6§§ë:ü±¦£c`Öד…äŠÙ晡Fl‘–B ãsc5òÇÆ¯Ø?㊿iOŠ~?øñçÂâg†4ÿ -¼ÿgÔ¯ô;k5½1OoxšÌ܉u;¹†£ ‡a/ôçŽ~)h_ µZøÎôÙÏâÍUtM)DIö«¶†iÄyE!?wm3nl/ËŒä€z Í¥RïÕ?»U÷5ò~cMÓ²ôkäôzôº4ûŸ_¿à‚ºÅ_¯Œ?á#ð=å÷ŒàÒ¿á)Ô|QðÛOñ.»ö«+h-žïGÔn¤ÎŸ%ÄVɽfŽò5|ÈŠ¬X·Eñwþ {ñƒâ^­ñm+㟀ô«o|JÐþ#E|0žâ]>M#ì"ÒѤþÛQ2•Ò4àïµ œ…_5D_aë´/üGÐ|%¬^˜¼Aâ{[ËÍ6×È‘¾Ñ§“ö†ó”M¿iƒ† ÿ.pqÐVŠ£ºiìî¼ÓüU–ÊÖZÈ¢š¶êÞ«Uþw}^®ìünð·Ãï‰?¿o|C±Ó|U¬üF½ø}¨é? õ†-¼Ðm`¸tã¨Øëñj+ ÛK>–­;_=»¼Fæh_vÝ•÷Ιû øßÂ?µŠ|sðßâÛh~ ñwˆ‡Œu '‡ËÜ^j‹¢Å¤¤sß‹¥Xm¶·¹6¾B¹–%ýð_–½Îçâÿ‡m>0Yø ãRUñmþ>¿‡“!/e ÐÁ$Þf݃\B»Kn;²‘ÒÒŠµ(Eh’åVÛ•YYuÑëv’èÐKÞ«9>®íy»¿ÅK¶Ï­Ï‰¿gÏø&ÇÆƒ6øyy⎵ÍÀ¾'×|I%” îl®u­]Ü]_Cöƒ®È±a¯'?”ÛÍË&Ó»íšæ´‹þñGÄÿø3BÔ–ãľµ²¼Õ¬„2)´ŠóÎû3*·ýš~‰9ÆFzZ©ÊRw–ûýá£m…Ïx7⦃ñľ+Ñü%|nµjqèúÔF #ûÓÙÛ^¬{BÉ›{ÛgÜ…—÷›s¹X†£úûÆW=ðÏ⦃ñ‡Ã÷Z§Ã»ã¨XÙjš†‹4† !Ùwcy5•Ô{dU'eżɸ ­·r–R èhzn6‚Šçþ|Rо6|9Ѽ[ðÎôêZˆ-VòÂèÁ$>|M÷[dŠ®¹ô` YøƒãÍ+ág€µ¿øêëìZ'‡,'Õ5 )åû=¼´²¾Ä›j#($ãS)F1roB£ NJZ½-ÖýzñÿÛûà±ûT~Æ?¾ü?¸Ó­5¯hòiös_»¥´r1˜/”ý+Õô}Zß_Ò-oô§2ÚÞ“ÂûJïFPÊp@# ŽÍb|aø½á߀ u¿|ZÔWHð߇mZóP¼hd˜[ĸËlYÛ¨áTšÒÎ2µµ"2RJQz.Ôö¥ ŒŽôT‚ÛCžø­ðÃJøÏðûSðÇŸXKÕ£XîKÕîô›À«.îÎX§ˆåG1º’2ƒó/ì§ÿ‰ðWÀ…ž/ðÿŠu_ˆW’ø·XÖfšK?‰ž&EŽÂçZ—PµHÉ¿S ÊÇöe–â-²ÊÂmòH%¿×uËü$øÁ¡|oðÍæ¯ðöâ{› cRЦi`xYnôûÙ¬nT+€HYí¥PÆ0$h޵»_‡õùù–æÔR¾‰¦½lÿáþK±äŸðKï…ºw‚µ} Æóâé²Ö¥‚{†—âߊ帔GåÜ6¦e‰|û’6U—xm‹·ý–¿à‘~ ø5ûxSá§Ä-WâíýŽ›¥.³s¥üLñ5¬RßYÚ´%¬Ù/Ñím‰–Söx„Qåî1¦Ï®h¦”’ëkü¶þ¼—`æz,|tÿ‚Pxâ7ì•âï†~Ô~#[ÿm[_Ía>£ñ3Ä×^]ôöMj†âWÔY­GÈZÕËÂ~bc%Žw<3ÿÆøs§| Ñü¬ß|Q{->áu$ƒâ—‰ã¹k¯³Çí»]DOäb0Vßx‰NX bM}EJŠNOù­ûwoëÉv@äÚŠþ^kÛÖ¿åø¾ìùö£ÿ‚Axãgìý§x7ÁÚŸÄ+I´mJÒòÎ]Câo‰çSêV·wv7ìÓ¹Kw4»Ì.U£(FG x—þ ­ðÇÅžðö‡«ÝüX[ G4ý¡?àøÙñûá_‹aÖ~![Øx&yÆ«üJñ8¸¹·þÈ}>ÜZHº†m¦BÒÍI'ošÒw§üAÿ‚jü1øãYüAâ‹Ï‹)¨Ü¬*ãOø­â:Ø¢H“m½¶¤‘)Ûî!fË6Y˜ïŒÿðP/³—ŽO†?hŒ? <â?&;Ÿì½sÄ––~T™ØþTÒ+ml`à×kñGãƒ~Úh÷üUáÿ AâNK“U¿ŠÑu é·yV°™ &}µ,vœ*”å¤Óë£ó¿~÷ùŽJÛöü7ûºŸ8|Zÿ‚Hx3â·í£¡üOÔµ_Åa•¬ÅªÚÛüIñ-¤²_]ÜéÒÀÖ‹ò¥­²­¥Ð’¼¸Ü¼9¼µ)èwÿðN†Ú—Å×ñ½ÕßÅ?í×ÕF´Q>(ø™4ÿ´ |Ü ÔE¨‹xÿP"ò¶ü»6üµî´TÅòÆ1[Föò»¿õè»)9ß›®þ~½÷yò?Ã_ø$ƒ>þÚúÏÅ+WÇòXK¤èñé–³|Jñ-Ì©iy¨Ï3\¬·Ì—¬·v¡-¥ó"R“b5ó{àø&ÇÃ/†~9ƒÄ^»ø°ú•·œoþ*ø£Pµýìoî¶¹Ôžùdm¹C´á—  v‚ö¹&KYb‘íßË•QƒÛ¶°Nb+#DøáÏøã]ðLJuí"ûÄ~ŽÚ]cK·»ŽKÍ-.UÚÝ®!Sº!*Ç!BÀnHÎ)ZñQ¶‹õþ¿!ÊRœ¥7»µþZ/ë»}Ï™¿f¿ø$§‚ÿg¿ÚÇÞ4±Ôü}q¿{ Ú<3|Hñ%á†쨬f±Ü_2]I¹ehä—ÌhÔǰ§–{oÿÁ3þ|<¸Ôåðåßŧ}[M¸Òn>Ûñ_Å7ÀA:lÆ.57K»4{dCÊ2žkÑ´ßÚsáγñÒûᆑã¿Ý|GÓ-ýç†!Õ }ZÒ„’Z†óvËd¨âE=Ðøkâƒã=c\Óü#¬éšÿ†oNÕíínRYtË–†9Ä3ª’csðɵ°vȧ¡£nWá·Ý­¾dͶýî–ü®¿ åÙcþçàŸÙÿ_ø·u¬k>½‹â½yuh øâPöÚ}Å¥œE&f¿ËÞ¶ý³&p¥J€='ßðM†𮿣i7Ÿ—‰c‚+֟⿊n.a™fO"âMLËlw¨Üв\£¤©÷êl²¬³Ìʈ€³3©&›zFý"£òвÿƒÝ¶úŠ×oÍ·ónÿðÝ’K¡ñ÷ìmÿ|ðgìáû2êžñޝã½B}~úîmBãMø‡â;Tò›U¸¾¶Ûo•­$ ,K+Áå´Ì$27±oA´ÿ‚eü0Ó~ë±¼ø´tínæÞîá¥ø±â©nVHUʺ}LÍ by7¤n«&¸b‰·ß⹎âÝf‚Dx]C««¬¤dzŽõ‘ðïâ?‡þ.ø'Nñ/½oJñ‡µˆ¼ûKMºK«KÈòFø¥Œ•qFA= Nq”^ÏÍ~*ëÍyeË+§¯õså¿Ùƒþÿào„?²ƒ¾üFÕ¾#^ê:V¦ ^çJøŸâ‹8&¾µ´h­<½AÚØ™f"Þ!G÷dǘÓmŸÚwþ %àŸ‹ÿ±·‹¾|?Õ>!ÙÞjZv«ýsª|Lñ5ÔpßÝÙ‹ukÇ{÷’æÕLqm/™ýáæGßõ­U&ê99ußð·ÝenÖ]‹§7NJqÝ_Sç“ÿÄøcsðßHðÅýïÅ£a£ÜMyÅñcÅQ\´³$)&û•ÔÄÒG‹xöÆîÉ.QT»–ã¿j¿ø$‚~;~Ï?‚|'©øþÒOßÚÜió_|Iñ,€Ä5K{Û‘pÿng¹¬Ržo1¡b†3Õ+õ½3ý㼿¯éhM6餣ÓoÏó>z×ÿà˜ ø÷â…wvzŸícð©göß|K ϧ[Ù]ÛªÄb¿âïuÌdÝœNê$ ) C}mE'&›èÓù§ø~éµÔjm^ÝSÉ«?øŸCÀ¼{ÿÔøcñ&}.O]üXFÑôË}"ßì?|Q`dfQo© š\}éäÝ,‡—v<×~ÓŸðGß~Ñ´¯ÃO\êþ<µ·ð­í̺ͺ|Dñ%¼—0¶“%ŒÇÉ¿U³7”ÒI–Ò¯™æ3ùŽì**“¶«ú¹?åo‘àÚÿü{៉~"¯ŠuK¿Š£UYḠÅ?ÛÙïˆ Oô8õ%€¯î×rùx~KXçÍüAÿ€ðn½û~X|c—Wñز‡D½†âÌ|CñÎÚ”ú•µâ~ÐÚ÷ˆt¯€þ?ðwŒµ? L¶Úݦ‹«Á}6‘+4ˆå"rabÐÊ`caØÔÓ—Âàö»Vù]¯Ãðò.MÚp—[_ïºüŸâ»žuá?ø&?Âßxœêú%çÅÆ¼1\C‹¿‹^+¼‡lñ<2~æmM£ÎÉ_kmÊ6×B¬ªÃ†ý›¿à‘> øñgâ—ˆ.5_ˆWVþ3ÔÙô¨ÿáfxšg¶±—E³Óæ[¯6ÿÜù‘]|^Ñ>2ézµç'žx4]jû@º2Àð•»²¸{yÔ²‰#ppÀd5<©É¾¼­Û·Wül¾muä©Ûìó'ÿoZVùÚïå~‡‘è¿ðLO…º†5#O¼øºlõѺi¾-x®i×É“ÌO&wÔÌ|ßxÄɸ|­‘Åq¿²oüSÁ_ÿdm?á·Œµ?]ÜOcc±>ñ#ÄÆÒÚ—(lX_+ØÆLº;)\m¬cëZ)Ù2TšM#æÏÁ-þëß5ÿèz‡Åmuw’ò9®~(ø¢yÒèÛIn…îQ34JK[ï19²1Œ_Ùïþ /à?…Ÿ±ïƒ~xÏSø‰vÚž&¡s¦|Jñ-–úÞÉm]­¤PI-íOÎVÖ2”ˆÁUÇÕ´U&Òšþn[ÿÛ··çø.È–—»å{|íËñ}Ùñ¯í}ÿið7ÇÏÙÄ_ ¾kì/¯`»:eαñ/Äú…¼sÜý­%ÔíPâÖ=°Ê$ vES#–ô½gþ ¡ðÃ_ð>ƒáíJóâÈÓ¼8÷2Y´¼SˆF“ϹR\ Æ»D®â1›C}þ¼¿ã×í¹ðsöXÖì4ßÚ_âŸÃïj¤æÎÛÄ:ý®›-ÔA¶—f‘K(n28Í)OdßõoòEYËäx¯í]ÿŒð_ǯƒ¾ðÏ…5oˆ6SxSVÒ&¶–óâ_‰\=”Ü:…ÚÊßof¸¸hÅÊC<»¤…Œ;1e;ŸÁ2¾x¿HЬu‹Ï‹‹‡l…™¶ø³â«Y#4“<‘jj×¾gýì¥Ü.ÔݱWÖ¾|kðí à+O|ñO‡üeá›ç’;mWE¿ŠúÎvÊ8I¢fV*êÊ@<EtõM»4ú¾o›[ÿ]ßpço¯—Ë·à¾ãäŸÚsþ #àŸ~!øWwg©øþÖ?j–i ñ'ݼúu½•ݺ¬F+þ.÷\ÆMÙÄî¢@ÒÄ7aâïø%÷¿j÷ZíçÅõ–ÚÊÛOAkñsÅ–ˆb·…!Œ²Cª*³ìwHAys»3³1úŠˆ¥Òêïói/Óïmõcsr·’åù&ßæÿÙ$üvÿ‚Ix+ãíkáˆÚ¶§ãø-l¬5K}^ _‰>%±–InÉ`6ko~©k²y‰–²…Õô?Á;>øç⬾3×®¾(®µ5Üw¬–ŸüKgaæG·n,`ÔRÙSä\Æ# ÜäœûErYǦÞ^Ÿp¤ù×,¶>>ñüÁº÷íùañŽ]_ÇbÊö‹1ñÄk;jSêV׈ñbûdV`C*µ’í·$Çû¢vúw†?à ü#ñZ?è÷_[[ŠòKõKŸ‰þ%º°ó\±lØK¨µ±Oœâ3Åã 01íñÞC5̰Å,m4 0-znFpqô©)¯v1‚Ú7·Í¹?ÅýÉ-’½ç)>¶¿ÉY]Û}YñïìýÿðgÀÛ/Æ_ô½_Çw6z­Ž‘kqñÄw“Á-ª^$æôÜ_¸¼…Ì~ZMæ¬D9@›Ž} ÀðLß…ÿ <@u? Þ|[k£ksfE÷Å_ÃåÏÁ'în57~ÉkíÝmt*ê¬:‡ðPß>3]ü:øWñsáçˆ|wdóÅ6ƒ§ëÖ×êðgÎA ¹fhö¶à2Wkg8é´ßÚsáγñÒûᆑã¿Ý|GÓ-ýç†!Õ }ZÒ„’Z†óvËd¨âE=îÚVÙ¯½ZÏÕZ÷ ÚMõV¿–ÖôécçÙïþùàƒ_¾*ëZ†­ñæÏÆÚ›6—|Oñ;Ëmc.‹ga2ܳê½¹óaºd¸bòÄIÊA xOþ ›ð¿Ázf»i¢^|[h|Gaý›yö¯‹*»u‡ÎŽlÀójlÖòo…?{I6ïMÛ]Õ½ÿµÃünÖ>xSǾÔþ!ø~Û횟†­ux&ÕtøwûÉ­UÌ‘¯ï¡å”cÍOï ÷ts6—kYzm÷=oÞìwjWÙ§øÿžÇÈŸ²Ÿü'Á_þx¿Ãþ)Õ~!^KâÝcYši,þ&x™; j]BÕ#&ýL7+Ù–[ˆ¶Ë+ ·É –Býî…ÿÒøaáßk¾Ónþ,?Äol÷?ÅÏt¦ÝÙãò.dÔŒÖã.Û„.‚A€û€{䲬³Ìʈ€³3©&’ Òê–ÙÒHäPÈêr¬ ‚:ŠR÷ÕŸMäÛo»oæ÷þ»Xùö[ÿ‚?xàÇì¡¡ü=ñÞ©ñîîÞÞËûN}/â‰íayí–eCi³PFµ„‹‰3 B8Ø„,¬cBºÿ?à”øû%x»áŸƒõˆÖÿÛV×óXO¨üLñ5×—}=“Z¡¸•õ–kQòµr😘ÉcŸ©è¨©MTƒ„¶×ü1p­(TUºwGΞÿ‚c|9Ó¾èþÖo¾(½–ŸpºŒ’AñKÄñܵ×ÙãöÝ®¢'ò1+o¼D§,1&¸Û/þýà¿Ú/ö6Õ¾xWñæŸv¶w‘h÷:§ÄO^B“\¼Næø=ûµô¹]±Üy«NÅ]ÍŸ°«’øññ¿Ã¿³gÁïøïâÕÔö^ð½›_j3Ãm%Ì‘D¸ÉX£Üò8PMjäç7.¬Æœ9c› øð?Býž~ÁះRx‚]2ÞY&VÖ¼A®]–vÜÙº¿žiØg¢—!G]}ŠM·¸E(« ¯Ÿ?àš?ò@üUÿeGÇ¿ú–jµôfxKÁZ?€´É¬¼¥iú=ÅåΡ,Vér\ÜÎ÷2 É,ÒË+·Vwf$’M4íëª)»Ã—Í?¹I~¦QR ¢Š(¢Š(¢Š(áø(Ÿí•ð“àÏü?ö\Ò~.üGðW†õ=]Öoµ+]KV‚Þ]>Þã@¾† gW`cIee°ÈQ“Å|ÁÿAý¥4Û_ˆìÿj¿Ž#ðV¹á‹ž o |?’hl4kï E¤\¾¤ñyï!i>ß4—†]°Éf‘f<4rþÃÑœã‘Þšvq—U÷|Q’kÏGö“ÐrwN+f¬þç}{k},ÓK]ÏÈ_ÚöÚøËeÿñe¦—ñOðñ´ñLJ-| \xªâÕ|IáÙÖÁ¦}?ÃÖÚ×öê]y÷Ê÷¢óu³!8¶XÈý#öþðwÃ_ÚÓÆwºÏíƒw<>øßcá}?ïŒ4ç°þÁ›N´kö’ŒI"%åÕäbVoܵ’¢•"_3õب, #¡ô¥ª£%IÂêé[çiS|”e¥Ÿ<“nóUºª¢zs++igi+¯Nd×nU«éù­ûßxGögÿ‚—ü]ð'‹þ%|TÕü{â‰K&á›­cíŸÚzsøOOê÷öûµª=¼öëu÷H`‹ï Wgû'~Ùÿ üSãÃ]ãö‘â¸u HºÒ ½ñ=Õü‚É®6«mjêȵ†ÚÑÚ#¼À0N¯½vÙÀÎ1žôµ÷` ÖÑåû’Iþ÷»µŠ¿½)wwùÝ·ùÙyw?4¿àŠ>&øEâÚöºøKñÖÿâF¯Žu+Ûx.üY¬×cØhèu@ïeó"û:Ü)Ù¶!ÎÎ:_ø'_í¯á?üHý¦üû:|dѾ2ëº.¢šŸío{yÙéÒú½Ùøëû&ÿÁNµ]3öËðëø·ã—¦økÇ)â; ß ø¿Ç£X×t½PÎ_KƒSÓ³­­ô „d’Ù,⸑¦®$hÚQ‹ÿ¼ý·5ŸÚ²+߈ÿíñÛPð7¦ñ¡á«ÿxwU¸ÖüBÖw'Q½A²‘¤þÏ€=«Ço1¶)(E+$ßûñká^‡ñÃág‰¼ñ"ÐÞø{Åú]Ϊ[¬­\ZÜDÐÊІRQØnRê x§Â¯ø'¤¾ø«àÏ|[øÃñGâˆømç·…4ßÅ¢ÛZèòÍi%›N[MÓ­¥¹”[M<@Í#®%f*\+,Â>ä©·gËd÷³´×{ý¥×¢z8£yÎj¢Z9]¯+Ť´µ´ißT›Ñó4¾Qÿ‚+~ÕšÇÆoÚ4Ý[â…ÏÅk}OáäZ¥Ýæ™ã™¼Kaez—P¬“jvSØÚÉáûë?ɧƒ2·¸T)ä“'ןðNþ>|GÏýOéêê½ø(Rv€3É÷¬ß ø+Gð5­Ü Òôý&ûÙõ+˜ìíÒ¸ºžC,ó¸PI$ŒÎÎyfbI$Öµ$§QM+{²þ5/+ZÖ²òµ–†)Z“ƒw|Ñ—þ Cñnÿ}õÕéÑEQEñü#â­Æ‘ûS~ÏøCñ[áïÃO‰Úíæ´š,¾'±šÈgÓ¤·‰VÌ\ÀÌÒNÉ>æð<¹~áûzŠ™ÃŸFôëm¼ŸG篠^Ú­üõ_5×ð?2à¡<ðÏìñCötðUÿíÀ]_Æ:ÌÒüCEÕtÝ2ÚöÖk Rò÷Vkkˆ C%Þ§‹í…ç˜mÀÇ5ÿQøÏâ¿Ùëþø}ñ³ÆF·£xRÖ´xãÇé¡Ûk—’Þ·Ù£·†ÏH¸“Ä:¸EìL¨­ °oÉ.ñú·HT67pr=¨¨E½ÛÓMâÒK·-î–Éì“Ôº.^×VKW}Û}ïªwßKÞÇâçíÏÿfºø‹ãŸi?>9Üxa|gð£FÕ¼=¬xƾÐt zçR¼¶Ônu‰oæYf†²1ùVÞkDVqå‰Lnœ7í-ûlÙ|ñwÅÀ¶ÿŽ.$ð\Ú­¯‡íï¼g¦ÞM¨%§ƒ­5 &Þ`Ìí>³,‘M¸ûÎõãì)u㿌Zçþ|]ø•ð£Vñm•­‡ˆ£ðì:=ݾ°–ÂEÙ5M>èÁ*$Λ¡1‚1¸¯Røð[Aýœ~ x[À? `¸¶ðçƒô¸4:9çiåX!@‰¾G%°¹,z’jùù¹¤£Ë¬­ó—2ÿÀR²òmhŒ×ºâž©(ÿä©'ÛYjßÞúŸ”¶íõñ‚ßö´ñt¾ø‰¢øjÊØørÿáU´ž.¹±·ñ–smi,³Xh¶Ú%àñ)¸ž[›w r¯ ˆöÇÒ[ø¹û|è¿h‹¾$OÚÆþH< ñ˾Ó¼+{â›4ëM2ñ´Ïíµž(I$içë1îE¿ösí*ÑÈOëáPH$GOjZpjœá$¾}zûÑv}>ËOK>g¢Zˤ“{¤¿®¾ý;uosó«O×|û3ÿÁVükgñâ—Å3âÏêŸÃ~V3ÿÂJ—Oy ¶òÁ¸±´"F”«or]ߢW ψN© })Øä‘Þ–£–>ËÙù¿¹Ûþ½oФ”euý=ßâöéÝŸ“¿²§ÇïøëàÏì9ðÇÂþ2Ðdø¡ð×ÄrøÛFµ¹OíŸ Ok¶ºœ÷ñm2YâædC,ª¡ÞT!ŽàÕÑÁ!|]ð[]ø§ûRßøö†Ô|aqmâÍbüÏsã;{ù"ÒMÒVMidÛ¸hŒ+t–«Nvqúx–±G;Kq¬÷œ( ßSÞ¤ª§'94\~mÁßÑrmæõ½­­ZžÑÇ¢M?’r¾õòZoÊÿØsâïÃ/ þÉßµG¿g?ÚPñG‹|,Þ9ÕþÖš½Ÿ‰n4koµ\Im«­™Ûç3­¬¥ÜG0FvàŽCösý³~'ß|ý o¿f/꿼i¥ü%Ms@} ÆxûM°Õciib¹°µšÃT˜J² -¡”bÕ€Yý 0!†Aê)çh''©¨Œyb£} £÷FQ¿â—Uée9óMÍ$¯7?¾Q—/žÍ]ô~¼ß”ß±/ÇU   œœP_ºïZÆQ‹¨Òø”òW6¾V­¥¬­ØÅÙÆRzÆöô’‚?r÷êÛ½Þ¢ÑE…|Ëÿ–ÿ”[üoÿ±fý kéªÌñŸ‚´ˆÞ¾Ð¾ iZv¹¢ê‘/,/íÒâÚê3Õ$ÁVÄSNÎãNÎæŒ?ê—è)ÔQH”¬¬sß¼aªøáö§«ø'ºÇõK(Õíô=.âÒÞóP%ÕJÇ%äÐÀ¤[÷’ œpʱíãñ‹â×Ájß>|OÕõľ#·ÓÙu_ ÂÚ‚Ûø†æÒ-. šš*Íin<·–]‘Éö9 Ë+:~Ъz‡tÿ Y½¿†¬lôûygšéâ¶…aGšiYd* ï#»³uffc’I¢:6ßoéÿ_ç{æ\©[[§ê¬ôþ¿;[Àí¿l/Š—^ Ö5+ŸÙ_âõ•þŸ,Ûi²xƒÂq¨,‚]òÆË¬˜•bòãÜ$ucç.Àøm¾uû~Ýÿ¾(þÀ¿ümão€?ü[âCBÑeškmWÂöÏâƒqfd›S·C©Å0ïD&92¤¦Ø°¯³ìÆPÊCAàƒÞªè°ðž…g¥øZÊÓLÓ4èÚÒÒÒ† X‘B¤qÆ **€P)ÅÙI>¶·•¯¿úÙXº²ÐùOöŸý·>.ø'ö"øãO ~Ï_¼5â+LÕ¬Zφ&›HX´÷š=V]ºœÉn’ŒÔÉ)1ŸÜ°#wMà¿Ûâ–¡û>è>$ºý›>*ê:õä±ÛM¤G­ø]/$‹ìÑÉý¡¼êËn!wv@‚A(e9Wý«i6ºþ•sc®Û[ÞØÞÄÐ\[Ï’)ã`U‘Ñ ¤#T–¶±XÛG ”qà *8ÑBª(ÀqŠ„šsmïËo+^ÿ}×ãÚ6%$ã–Ü×ó¿-¾ë?ëšÿ~Ú¿·—Æ_…ß³‡ˆü û>üOðþ·}¬é¶×&m_Âó¾‘ëVæ)‡öœˆíuÒGˆI°¸.bÆõõ_þÖ´_x{QÒ?f‹½þ±ï}¥ÛëÞK Ç1DK‡—XXœÊ€J¦ %X*ÙZ÷ wÃö(ÓZÏÄÖ6z›ºHÐ]B³FÌŽ«2®ªÀö*äUÊ,ï¸]rÚÇÄ·Çíûñ—à‡ƒ~]|2øñÆãÅ>,ðÝ®¨ïªxjQÝjBôf¨·úT±¨U™’¾zŸ=b¾½ãOÚÛâ†bÑ[Ãÿ²÷ÅŸ¶§¦E}v¶zÿ…¢:LìÎÎo?XŒ<¨X´[ã"EÃ’rÖ|?aâ( OXÙß%­Äwp­Ä+(†hØ4r¨`vº° ¬9dUÊ´í¼Î_'¥DÓ>üÍÃ^òÝKçvï÷5ÿ k|7ûRÁB¾5|3ý©>xsÀß³÷Ääx²úðjvCVð¹“ÄЦ»ûú™òeµ¸æGf…ìÎ#y•?´|Aý­>'xCƳéžý˜>,ø«N‰adÕ´ý{ÂÐÛL^$w —:ÄRƒ3FÙ@ FJ–R¬}ÂÿÃö¦¥cy©ØÙÜÞiŽòYÏ,*òZ3¡Fh˜Œ¡(̤®2ކ®Us+§oëóün>2øÍûv|`ð?üÂ^ð—À‰š¿…n¼=â)Ú]SÞ#kkÍ8u(}I%Šæehä0ÈßlCå>Âcõ‹ÿÚ§âM§Å×ðõ¯ìÕñNçB]TX¦»á‘§µ¿›³íÂՅו·÷› >nÞ<½ß-{LþÓîµëmVæÆÎMRÊ mmï7E+FÒF’¹QÚK(8c£*bíEî¯;»ëè¿«Y+›R½•¯øzÁ¾Þ§Æ_ ÿnߌ.ÿ‚†øŸÀž%ø ñ7M𥿇å¥x~ÃB–ñôK;7Ôn ÝÛA Æn¦*ªe¨ܪ"î98U…\ª¾]£üÚI7ózëó»»qmeç&ýwKåÿ ed¾#ÿ‚{þßß~8~Çú‡‹~%| ø‹âOÕ58m×TðÕ¿öú¦·wj-í×ûF4í F˜DÀÆ6”°gõ›_Úïâ×ýgW¹ý—¾-ÙjšużÚ<ºÿ…ZëQŽE”ÉÒ›b¾Ë_¶—íÕñƒá§ì ñÆþ øñ?Â~)Ót-nH$¹Õ|/s'†~ÏaçCªÎ£S–) 3*14§ìÎ2oú÷@ðý‡„ô+=/ÂÖVšf™§@–Ö––¬0ZÄŠ#Ž5QT€F¿ Xx¯C¼ÒüQei©išŒmwiu ÍÔN¥^9#`UÕ”T‚$º²S”œU¯·–ߟ^š»[K])FŒ¤®“þ¿¯¾úžíñI>hÚÌ?²÷Å»íSPžh.4˜µÿ ­Íœi,—2;k“dUTvpa}ꀡ;ý·¿n¯Œ_ ?e­#Äßþ|KÑ5ÝSUÓ¡¼Y5o M&„­Z[' ©)é:Fs¦~Ê¿õ9õ+gžîÖøM$Ò¤YåŒC1“ZTwd&&‘6Ì€°pè¾sû`~Ý?~ø³à¥¿Ã߀¿Ì>-ñ ”z¼qjÞf¹ótëù¤Ñó6¥òÜG$1;J¥a" 9ÈWû.©ê¾°×e³}nÆÎñôëwhÓ²i‚²‰#,Ç î7 1ÍL“n-=¤ŸÉ;µ÷Áººv¤—5Öñ’ù´Ò'¯ågf¼;Ç¿µ§Äï Ï¥§†f‹'[ý2Þúáìuÿ Â4éäMÒYËö^2ÒÄ~VhÃÄOÜw×~ן·ïÆ_„?µßÁo |8øñPÐ|K©ßÅ~jžð”*hs] {VŸQ ÛÎ;H`Vû;„iC(·*ÿ‡ì5MJÆóS±³¹¼Ó䳞XUä´gBŒÑ1BQ™I\d1 Zv×õ§ÞfÕþïéž%¯þÕß4Ÿˆ«£i³/Å]SJ3Ã×`×¼0–j޼ž\šºÏ¶=ÌyY;ÐÀ‚|{Ä߷߯M3þ {¤|6ÓþüD›Á“xSRºhWTðÐûsE«Y[G­Fí¨ù‹jË&afIÏž¿èä‚Síª¦þ°“^U{6Õ"·kD¼0©¸HY•š!&7,ˆÅs‚TÂ6¡Rjés]w¼Z_siþZÙ¥%Í Fú»[ÊÍ7÷­?à]?³ýª~$Ü|^_Ü~Í_ ЛWþÏ>(msÃ'O[;Ëûq„jÆëÉÙûÝ‚7o^ï–¼Ÿá_íÛñƒÅßðPßøÄ¿¾&é¾·ðç‡çXn5O 2hâÿXŠmVg‡Rie‚d¶…DQ™d_±9òP¸2}›TáðîŸm¯Üê¶ö6qê—Ek=â¢âxbi8Þ@72#M1U' dr1¸åEòÚúÛñõÿmß•´m8Ê=]­åª—õk§á>ý¯>)xƒÄæÇ[ý–~.hvb+‰?´.üAáI!-Nñ¦Øu—“2º$Jvà4Š\ª†aæ?²wíãñ‹â—ÇÚ?¾|O‹Nð¾¿åi±Mªø\aðîxšd§™f¸¸•äIs,köèÖIcTu‹í §¦xwOÑou ÆÎÒçVœ]_K +ÞJ#H„’°‘ÄqD››'lj½¡î·}nšùÝký~WMó.Ý¥éøùžà¯ÚÛâ‰ãÖˆ?eï‹>:n™-õ¢Þëþ”ê³£ [8|bM’¸f!¥Ùw8$柱íÏñƒâÿ„>$]|Iøñ*iü9âG¦»ê¾Qr-u&† 1¤?Òc(e”IÏžùVo²jžáûÅ:x~ÆÎÅ.®$»™máX„ÓHŤ‘‚¹Ù‰,Ç’NMMŸ;•ôåkæÚwõI?ç5×2äå¶¼ÉßÉ)&½iÿÁQ·„hßµïÅ=OÃÍö¡û,|]Óï4ÑµÓæñ…}W|›\Bɬ´kå¯ÎÞk¦G ¸ñ^sû ~Üÿ>-~ÃñŸÄ/€ÿ¼Câì½>ehu_ Àþ,i‹‰n-ÔcŽˆ"³,â݈‘v#À}“U4ØxWF·Ó¼/ei¦éöh#‚ÖÖ† "€{CNàšI«7üKý³~*è_³gŠ-ýŸ>%ø£ÅzΑ¤µÔVz¿†mäÖ„ÚzO.«}N(£·yx?•02¯îT·ëË«X¯­¤†ö4𔤑º†WR0A‚㓤ÚhUµ†…moeceAoob8 UDE*€ 1WeQ>¼¶òåæ¿þuO(òÃWäòæ¿íoºÏúæ¿ÄŸðPø(OƯƒ°W‡Æ·íßñ‡á'À_kŸþ|NÑõMoÄ^ƒP-ªøbfÒ–ZÙɦÌRtio-ØÆ’C½#ûdlòÂÈæ/NñGíuñGBÒ4+ö[ø¹¬ÏªÙ›Ë[oxU$ÑåI·œË¬ª»”%Ý‘6Ì£vðê¾ë®xwOñ=’[x–ÆÏQ¶Žxn–+˜VdYa‘eŠ@¬’":·UeV ¹EýÖ­ö›ôVZzW»w¶×nŸÓþ´×m?lÛ§ãŸ|·ø{ðâY‡Å¾!²WŽ-[à ×>n4š>fÔ¾[ˆä†'iT¬$BÁg9 þ‹âïÛ⧇µ xt/ÙSâþ»ÖV×/=¯ˆ|'C,°¤’[°›YF/ ³DÌBѱFt*ÍïZ¯‡ì5Ùlß[±³¼}:à]Ú4ð¬†Ú`¬¢H˱»à GsW+8'$úÉ¿•’·ÞŸü=Ûs’“–ÑKçÌÝýlÒÿ€¢—Æ¿´7íÑñ‡á¿íÇà_xà/ĽwÃ7ÚN¹<±ÙjÞEñ#ºqŽ{v¹Ô’H’ÜÜL®²KWjÊSÕüaûRüHðïÅYt ömø£¯h±ÝÇn¾$´×<5„±¶ÝÓˆ§Õ’ä"nlƒc°áOö{¯Ø_k6šíœÚ…‚I­Ó­5²É·ÌXÜŒ m‰¸3µsÐUÊpN-__×úò°¦Ô•–‡Ä¾&ý¾þ2iŸðSÝ#á¶Ÿð/â$Þ ›Âš•ÓBº§†‡Ûš-ZÊÚ=j7mGÌ[T†Y3 2N|õÿG$žÏáÚ›âF¹ñZ=Xý›>(èú#ÞIlÞ$¹×<4ö –Ûpb‹V{’´¢ãpÊŽqìïáû 5èõW±³mR+v´Kà ›„…™Y¢cpBÈŒW8%Aì*å8éN{®k¾÷“kîM/øJe¬¤ÖÎÖò´R{×þ Ûø“öiý¿>2|Rÿ‚€üIð/¾|EÑ<-¤i^š.õO ;xY®#Ô[‹§·Ô]æKƒ*‹NÉå6å‹?7­øö¹ø¡âß?~ËŸü1j-ng×Úÿ…f„É$pí·Ö$“|®‹ »CH¥Ù3¯ºZø~ÂÇY»Ôl¬láÔ5Ž;«¤…Vk•w–²8œ.÷Ú 8ÜØêjå6ïÓ§é¿ëùÜŽÿ×ôÏŠ¿eÏÛãã/ÄŒß4¿þÏŸžÇºÿ•¦[I«xYNˆÃÚuÚi’4zžešây¤•%Ì‘¯ÛcW–0Œ±z¯„ÿkŸŠ Ó5Ùõ¿ÙsâÞ‰6•aö»;{­²>±7}–°ê’l‘åÝ)Ž=°¸ß¸¢·ºižÓô[ÝBçG±³´¹Õ§WÒà Æ÷’ˆÒ!$¬dqQ&æÉÛ¯E\¦Úi+}”¾vµýÉ^úÝÝ^þÒþµó>/ýˆÿoŒ_¾ xÛVøð â~¯¨è>%ñ¾žËªø^ÔßÄ76‘iqÔÑVkKqå¼²ìŽO±ÈVYYÐËêZíkñ?UðV»©ê_²ÿÅ7PÒžÙlô™õÿ 5Ö°%vYXhPBY¼é#$8Ù¸‚¹h~Óü1föþ±³Óíåžk§ŠÚ…i¤ieª€ ¼ŽîÍÕ™™ŽI&®TÏÞJÚiý_®£m9I¥»oäö_/ëK%ñgìIûzüføŸûøKÅþ:ýžþ(ø«Ä—6-$öÚ¿…­ÿá!ó’c-åºN$Ž(ÌQ†Y>zm€r›Ÿ´ÿí¹ñwÁ?±Äxcözøá¯éZf¨-`ºÖ|14ÚBŧ¼Ñê²íÔä†Kt”`ƦIIŒþ徬Ð|?aá]ßN𽕦›§Ù Ž [XV`Qü(ŠQì?VÒmuý*æÇ]¶·½±½‰ ¸·ž1$SÆÀ«#£H$F8¬ªÂS§(EÙµ¿o×ñ¿f©U„+F£âíÝvíúwV¹ó·‚ÿlŠZ‡ìû ø’ëölø«¨ë×’Çm6‘·át¼’/³G'ö†ó«-¸…ÝÙ ¡”æ5\æ¿ðPßÛóã/ÁØÅ>9øoð'â7…üS™{/ŸyªxjäxQ¢x–+‹´Œ©2J$r«Ü0òÎõ\®~×µµŠÆÚ8l£ŽaP‘ÆŠQ@ÀŒU}Ãö*Ñ®tïXÙêZ}â絺…f†u=UÑVÄWDäœÜ’ѽ¿¯ëåc’”\!ËV·óþ¾óœøñ]ø£ðúßWøà_|9Õ%–D}Z»°º»‰Tád2X\Ü@CŽ@P uôQRÝÊŠiY»…x·ìñ]ø¡ðoÄ:‡Ä-N}ZúÏâŒt˜f•Z;K?ê6¶Ð€Š#‚£Œ€’NIöšò¯Øï঱ðáv·£xâ]>[ÍGÆž'ñ FÊW’1m©k—×öêÅÑHCuq‚†˜ÅÆÚ߷ꊕ¹ë̾ëJÿU¯ý¶õŒøoi¨þÈÚ§€ôYôÇ»¾×ï}A~Ü?Û,/,á³VXŽ»ˆçŽ8·–tfp|°kwbzþÏàæ\š}Ÿzþz{½›Ö÷Ñœ´c(ÆŠ©«´¹½oíÝ•­mOMoø*€æðw†/4_ üMÔ|Mâû½FÓMðl™|H³Ü-ä³YÈTA [á&Y]Tùð¨%äU>Çð+ãw‡?i„šþ^M}áÿÛý¢ÒI­¤¶™pÅ9a•Uâ‘VFdWÅ¿¿àŠš×Çïìo~Ð>8øQãøo^Õõ=:Mgá:ßxb[MP[››K­çS•äu–Õ$Šæ+¨dOºw©`ÿYþdzu·ìû7x_áæ•}i©Gáèe si£ÚèöÒI,òO'“eh« ¼Aå`‘¨%T(fv˶0W…äýí4ùk¯“þ­©O™JÝ5üô¿ªí¿C„ý¨?o+ŸÙÃöˆð­~üAñu¿‹ã¼–}GEÒÍÌpˆmä•c‡ ²f?I]ªÁ²zUïðQ~ÏÚôO‰4OëZ´Zx«Z±Ð|;>§qá}%™^j)|¥-ê±®ù_Ș¤n"r·¿kÿÙ£Åÿ5뿳ÿì~xÃÀ÷·sÚßjþݳ¸†êÎ[Yc’Ø\Û°aæ$¨ë(ÚñÊêYO›|Iÿ‚qøÞë^‡Yøñ¿TðÆ¿®xOø{ã=[Yðô:íïˆ¬ìŒæB2Â-5 ooœË4$Î [±E¬eí9_%¯}/þvéÍÊŸ[7næ±J÷“ÓËÕ'ó·3]6»è}Ká_éÞ9ð¾›­ø>öÛRÒ5‹X¯lo-Ü<7PJã‘pÊÊÊÀŽ ŠñOƒ?>&øŸöÞø¯á¿ø‡Á×?¼i§I¥iÖžžßU^ÆdS=û_i?¾xgÁžŽh´? iVº6ž“Hd‘-íáXc ç–;rOS_3|fý‡><ø·â‡ÅÝkàíáiÿ¬ ÓBÿ¹¹¼Õ|?6ÒA¶·ñëp´/$‚SÂü§=kS¿.¶o·šïnÉÛ¡Œ9Ü#Ͼ—·§O+ùêzUÿíQp¿·Ž‡ð©­õ-*Ò÷ÃÚ¦¢>ßáù„zä–ͧŸ:ÇQy^\+xÉ,mfySi<æ±ÿFð.‹®jZdÞø¡6¥¥øþ†ÓZÁá‰e˜êÓZ}²2ª›slc›ÏáJŒHŠc‹þ5ý¶<ñWÿü¦è~±¼Ò,4¯‡·—SXß½Y¯Æ±i™´å1Ê Q†Iq“½­þÁ–Ú×üJøÝ'‰îSKÓ´Ì¿„¾Â†Ú}q!šÎkí· “O»»³1í!•ÐäÀ1ONE-µ¿ßÆ>êµìÚ{"äÛRikÿ߃´ž×I¥«"ð'üÛá·ÄoŒ¶>ðÝ¿ŒÍ¦±â ï i(›Ã÷xwZÖ,’gº±µ½a‰¥Ðm»[Ê‘Èì¥kèjøKà¯üïÃÿj»øCSðö&—âËïÛ>iòxÅî.ÞâV³›ÄŽìïf’Ý; ép"ŒÜS»îÚjÎoâë÷/Öÿ+z·6½¤”»Òþ¯ô·Îþ‹Æg¯ˆZß‹?iº?‰5)ï4¿ xƒJ´Ò-P%„Rè–7"PHi¦•ÉbÇ.pq€=š¼³àŸÁcáçǯŒ¾&×äÓßMñþµ§jZÁ+¼ÉM›‰Ô Þm´„. •9•§Q ÛÞ.¥¯§eùQTAóïüãÿŒeŸØËÄ¿>êÞÑuo ÜØÉ=ωtÙo´ôµ–îyšEŽêܦşÌÞdÀG;—Ã>Á[%ð&™ñ®ÿãÿˆ|'ñ›ÀÿbÓofñ÷Â]gÓR;ˆo$º¶»¶ûuÚ¤¶BÅ^VŽáð—D9ÝôWüöY׿mÙwYøsàiž¸×.¬å¸Ôï¼?ý¹“osÁ‹ì¿i€í )bä,6ä‚3ÿmoÙÄŸ´ÿì]â/„ ü]áo‡òøÏM›G×5Cá&Ô`’ÖâÞH®~Ëf—°y³8uv’P¡H*äî®h©µåe¿m}:Y8»ß¹¢å“Œe¶ºöòõûÖ½,aiÿðUOê :Ñð§ÅëA¨ßXéÞ°¾ðEõ÷Œæ¼Žy`T3"™ÿukq,›ü¿"8Ì“yhCkãÏüËBøuð#þ5øWà/ø½õOØø+UÒ×G’Ú÷ÃW’jv–W÷ñ?Í Èa¡gc×Ù"È{/ŠŸ±¿Ž~0ü øqÿ WÄ­Óâ÷ÂÍ{þ-Åzo„Œ:KOä]Z§Ñ录ž²½šU»WÜ|ÄxÈsº—üWRÕÿeøSUøŽ÷|Oã{‰7þ/›CSfúåí•Õ¾Ý-gl‘tÛKqoçïò“&c!2?åì¯ð&­Õµx_²Õ{Kíª¬®ÌW7$™­{'i~¼–ßG+ÝØô/ˆ_·?‡þx‡ˆ<)ñOxòæ{MÂÚKâ¶€;LÍld1¤iæ4²ÈˆÆ7n‘²µø)OÇøiàø/øº÷â=ÅÕžáÝCšMvæ{7hÒQ´6’#G;\˜–'ƒ2«sZßì!ñïþñ•ñ«ƯßëKâ­OÃ÷I¾¶Õeó.´ÖÒ…ÚIšyv¢K±$_d‡t’ êùÚü/[øq࿇ÿþ)ϧüVø}w®^Íâ{@U²ñë—mÕÒóM†k}±Ír#–1ñ4>TjÓz¸¶wî¾ï/%Õ»>É–­§£ýmúi¶º´u'ÿ‚x'Ã^ðÅâxKâÆ¥«ø—DŸÄ’xvÇÁ÷rëz&›žT×Z…ž@L¢ÇóI1V¤»N ø¡ûEøÄ|PøâÏž1ð.·ðoâÞ©g¥ #áë‰u¸îtëëèï­µ1|±¬l–öàDÖŒpXïä…â_Øâ¤wº7‰þþÐ7oÄéü5/…m÷\œ¶¾¼Í鵋/y_G [¿7"åô÷ÛÛNT¯Õ?®¨ª´Ôì–ïö¶º¸Ôln‘ÕvíòÂZH Ýœ•à‚Htl«Órø}ûöþEü™ÆÞvc“ýÔÒßÝ·þÿä·ù\ö(¢¤Š( Š( Š( ™ÿà¨ÿµ?Š?c¿ƒÞ ñ‡€¼Gà¿ i79Ñ4/ßx—JšúÚÛM¾»KigFŠæ%ây››z¸!AÜ<ßöfÿ‚©Eâ/ |PñoÅxÇ^‹âŒßþZx×2j>"e¶ŽåbE7S ©‚Ë wã[)¥r¨O—÷ì¹âOÚ«Ã~Óþx×LðQð‡4ŸÜËwáöÕ΢4û•¹ŽÙ@ºƒÉß".é>s· ('#çÏŠßðE™þ;ø{â¿Æx[Ä—:÷Å3ñSÃ1ßx+­3F¹6bÁ¬5+‹É#ÕmšÕQÚ@û¤GFÙ唣5=Ûvôn‡è«5Û[ßš(*®g+úÚ¯êéß¾›YžÎßðRŸ _|1ÓüGá|SñÅη{áÛíOð̇SÐ/¬ãi.bÔFH­¶*d3I¶]ñùFMëœoŠ_ðT?ÍðGš¿ìýuâokÿ<3{â[è~½×îb´‚5ó/îôøÚXa’hQ¢yay$a dÈpGö ¼?}47?f“O]AQn็̊⊭嵫(RW‹WéÓ¿&Ëþß¶ûFú·bàÔydõßOû{N|ùÊÊÉ^ÝÀø*ÅŽ±û$|ñÅ­ Ä^(øñƒÁ©â³áÏx~{éRá‰îîü£#-½¼mÑt‚:d–Ú|¿Âõ¼’òî{ymînGØu+(-‘¢™•!Šåå²ÎIZwÖ×—Ê×—éËÒêWÒKE•ùŠMÚ;ù«~nývZ´Ï©>üJ·øÅðÓEñF•¥øƒE·ÖíVé,5Í6]7Q´Ïü³¸¶”‰Á#ÜdkåÏ_ÿhß‹ÿþ4i¿ðO©~i‘|†=1-×#´¾øk>¥w¦¦ƒ5¼–0›£­Çö†o±[ùÒº!ó ˆ÷«ñ3þm¢üAý¨uˆÇZøxÒxÇ]Ó|Kâ õ_†VÆ¿m{j–Ë"躭ԬtûyŤ{¢–+³’SÆÎ íÏQ9Ù&úiexÛMv2vmóYꮎuztäµr¶›júë¦ïmKµz×?à¡Þ´øí¨øÂ~øâ‹­[²ðÞ¹­hž¸½Ñt FñcxmînF2U'åh„‹ʆfp®'ö|ÿ‚ˆ?ü,ü&øæ—þ0ø±©jÔW~ð¼ðé6ö6ZÕΜ—·h×3›Ï™ó%`X¤ýѹiûüCð'Çm{Uøñ—þ_‡1ñL>/×|4þŠûQûXòþÕަóªÛZݘ#3G%´òó˜¥ˆÈ ~Uðþ 5ñà7í)mñW¿| aâ­_Äzž«ãyt¯†ÓY§Žôûéc˜ØÞÖeÚöÎŽm®FZåv2´«6T›r‡>ŠÞ÷¯*Ñysók¿*µ›³7«Êá5O⺷øW5ï¦ír鲓Zò¦z·Âßø*/‚>5xª †ø›«ézšêçG×bðùþË×_K.·Q[JdæoÒ5‘#2JnPXC£ÿÁW~ø‡Ã^Õt-âÝ¯Š¼¨ø÷JXü;)–òÇO•b¼S9û\FH‰·ÆìHž¸¯5ý•¿àçÀoÚ_ÿ¾ |Eðwˆµ?Þj7³jÚ?ÃØôø¤]Ç4kk®ëßIý¥m˜2£À®Ò[[;HL6™ÿ‚ø·á=oñxãÿƒ­<3à ø—Â^°¼øc-ÕÕ½†µ,r¹ºº]f1q<&ÞØXâVXÛ( ’3¨çìâà½ç{ô•¥dûÝòí¦Œ¨ò{WÍð_¦í]~—ß¿•pý•¿à¨ß¿kωc¿ô‰zF¤mëÍñ…ntÛPD·KžA°NÖ—öw+såL¤àåGÒ5ñ÷ìÛÿþøÉðwö‚Ó¼añ/ã_€¼S¤E}5õö•aðÒ}*{¢úEŽ˜;¦Ö§še¬™1HKG Ê#ûºj('î=?àkøéò9©óÙsïøzQYšQ@x/ü⧈¾Á>¾,ø·á.­>…âM@–ëNÔ!Ž9$´”ÕdVBFOÞR=«Þ«Çÿoï€ÇíQûüFøwðþãN´Ö¼]£É§ÙÍ~î–ÑÈÄddV`¼vSô§&®8»4Ï_ŒîIêE-".Ôö¥¤É[+…sß þ*h?|?uª|;¾:…–©¨h³H`’—v7“Y]G¶ERv\[Ì›€ÚÛw)e “â·Ã +ã?ÃíOÃ6}b=/Vc¸m/W»Òo®<»»9bž#•ÆêHÈ<Ì¿²Ÿü'Á_þx¿Ãþ)Õ~!^KâÝcYši,þ&x™; j]BÕ#&ýL7+Ù–[ˆ¶Ë+ ·É –Bäuný´õþ¿®÷hò§}n¯égwý~·_];ˆÐ³ðdÖŠ:Æÿ†ñŸÃÓ©xoÅzm¾¯¥Ý˜d€ÜÚÏËž\ª®›‘Ôíe 3‚¯´ÿ‚_|-Ó¼«èV7ŸM–µ,Ü4¿üW-Àx¢?.áµ3,KûçÜ‘²«ü»Ãl]¼oìµÿ‹ðOÁ¯ØãŸ >!j¿ïoìtÝ)u›/âg‰­b–úÎÕ¡-fÉ~klL²Ÿ³Ä"ˆ/ty68Ù©_}-ç½þïë} +-O¨¾ øóJøYà-oÄþ:ºû‰áË õMBãÊy~Ïom,¯±fÚˆÇ 8ÀÕíV·×ô‹[ý)̶·°¤ð¾Ò»Ñ”2œÈ#‚3_0ütÿ‚Pxâ7ì•âï†~Ô~#[ÿm[_Ía>£ñ3Ä×^]ôöMj†âWÔY­GÈZÕËÂ~bc%Žw<3ÿÆøs§| Ñü¬ß|Q{->áu$ƒâ—‰ã¹k¯³Çí»]DOäb0Vßx‰NX bMBm¹ß§-¼ï~o»OÿºIEF nù¯ån^_¾ïú^÷µüOø¥¡|ð|šÿÄ{Ó§éQ]ZÙ´Â &Ä·71[@»#Vošiâ\ãvN$tòíGÿ‚ð7ÆÏÙûNðoƒµ?ˆV“hÚ•¥åœº‡ÄßΦ5Ô­nîìoÙ§r–î"iw˜\«FPŒ@ñ/ü[á‹ÜZHº†m¦BÒÍI'ošÒw§üAÿ‚jü1øãYüAâ‹Ï‹)¨Ü¬*ãOø­â:Ø¢H“m½¶¤‘)Ûî!fË6Y˜š´nµÓúéÿæž·ª|TÐtoŠz/‚õ+ã‰|C¦_kžD„Okg%¬W2yv.Ç¿´Yƒ7™•+èkä‹_ðI|Vý´t?‰ú–«ãø¬"Òµ˜µ[[‰>%´–Kë»:XÑ`¾Tµ¶U´ºA——‡1·–¥=ÿþ ÏðÛRøºþ7º»ø§ýºú¨ÖŠ'Å&Ÿö/›`ºˆµoê^Vß—fß–¦6qƒ{»ßË]-òÿ>¶W4•ù_§üÝ;þú¦ñSAÕ~*êþ °¾/âm K²Ö¯¬ü‰†Òò[¨mäó ìmòX]ªÅ—ËËKt5ò?Ã_ø$ƒ>þÚúÏÅ+WÇòXK¤èñé–³|Jñ-Ì©iy¨Ï3\¬·Ì—¬·v¡-¥ó"R“b5ó{àø&ÇÃ/†~9ƒÄ^»ø°ú•·œoþ*ø£Pµýìoî¶¹Ôžùdm¹C´á—  …öSëý_Ö„ÔT¤¢ôÒßv¿sþ´»õ¿ üRмkãè>½7:¯ƒn ³Õáò$O²K5´w1®öP¯˜f‰²…€Ýƒ‚|•û5ÿÁ%<û=þО>ñ¥Ž§ã눵ûØfÑá›âG‰/ 0ÿeEc0½Žâù’êMË+G$¾cF¦=…<´ Ûxþ ŸðÃá寧/‡.þ-;êÚmÆ“qöߊþ)¾ Ód†1q©¸Š\}Ù£Û"Q”óI]­§ý[_À&’k—Ëô¿êz×Ãß‹þø«¨xž×À:’êÖ@ÖC$c½Ha¡%ÔÄw0¶åÊüøÎA¥¯Ž?eø#Ÿ‚gýâÝÖ±¬xúö/ˆzõåÕ ƒâ?‰CÛi÷–q™šÿ/xÚCö̙”Q( ôŸÁ4~xWºþ¤Þ|Z6^%ޝZŠþ)¸¸U†e™<‹‰53-±Þ£sBÈ]rŒJ’¦´´xÅ¿ñ4œ—Éù¾ÚÚî5¼¿ÄÒô¾îû÷Òö^³ð“âÿ‡~:ø|*Ô—VÑgº»³Žåa’ ÒÚÜËk:í‘U¾Y •3Œ¹Ò;ˆÐ³ðd×Ç¿±·üóÁŸ³‡ì˪x Æ:¿Žõ õûë¹µ 7âˆíSÊmVâúØ[m¾V´,±,¯–Ó0ÈdÞŽÓþ —ðÃMø{¬xfÆóâÑÓµ»›{»†—âÇŠ¥¹Y YV?*éõ34)‰äÞ‘º¬˜BáŠ&ÕSÝŒœwéýz–—º¨Ù»Koëúþ¬{Š:Æÿ†ñŸÃÓ©xoÅzm¾¯¥Ý˜d€ÜÚÏËž\ª®›‘Ôíe 3‚¥ø©ñ;Dø)ðÇÄ^2ø—xtïxOL¹Ö5K± “›k[xšYdòãVwÚˆÇj©cŒOóìÁÿð7ÂÙÁß~#j߯u+NÓ¯s¥|OñEœ_ZÚ4 Öž^ mlL³oŽ#û²cÌi¶Ïí;ÿ’ðOÅÿØÛÅß ¾êŸìï5-;UþƹÕ>&xšê8oîìźµã½ûÉsj¦8‰¶—̈~ðˆó#ﺪ1””5]<öÿƒnúm}.”c)ÅMÙ__ëú·Ÿ_¬à™naI!;’E §È<ŠÁøŸñKBø5àù5ÿˆ÷§OÒ¢ºµ³i„M‰nnb¶vF¬ß4ÓĹÆìœHñ“ÿÄøcsðßHðÅýïÅ£a£ÜMyÅñcÅQ\´³$)&û•ÔÄÒG‹xöÆîÉ.QT»–ã¿j¿ø$‚~;~Ï?‚|'©øþÒOßÚÜió_|Iñ,€Ä5K{Û‘pÿng¹¬Ržo1¡b†3Õ+4~æ¿×õùùÒ´”yôïýzOsëzçüsñKBøm¨xrׯw¦Îj«¢iJ ’Oµ]´3N#Ê) û»i›sa~\g$ãZÿüág‰tÇS¼ø¾ ÐmžÒÐÁñsÅHѼòÎ|é#ÕÜ>ùŸJ]Âì@B"*ñß´çüGÁ?üCð®îÏSñý¬~Õ,þÒâO‰ayôë{+»uXŒWü]›³‰ÝD¥!ˆi“iÆßÌ“ô¾¯îû·ÖÖv”}뿳&¿Ä“i|ßß¶—ºúÚ¹¯ü_ðï€üqá? ø³R[MkÇ7Wz%±†G7ÒÁm%ÔªTªm†.T¸$äþ=ÿ‚j|1ø“>—'‰®þ,#húe¾‘oöо(°  ²3(·ÔM.>ôòn–CË»kοiÏø#ïƒ?hÚWá§Ž®uZÛøVöæ]fÝ>"x’ÞK˜[I’ÆcäߪÙÈÊi$‡ËiWÌóüÇ j××úíý~&oôüO°«š¹ø¿áÛOŒ~¸Ô•|[£Ï¯ÁaäÈKÙC40I7™·`Ä—®ÒÛŽì€@$y^¿ÿÞøgâ_ˆ«âRïâ¨ÕVxnÁñOÄöö{âý=I`+ûµÜ¾^’À–9óÁ <¯~ß–åÕüv,¡Ñ/a¸³üF³¶¥>¥mx/¶Ef2«Y.ÛrLº!k§gR  æ¿•¢Ü~ùY~^ñR¿$šßKyê“ü?Ï[Yýƒ\öñSAÕ~*êþ °¾/âm K²Ö¯¬ü‰†Òò[¨mäó ìmòX]ªÅ—ËËKy]ŸüŸáµÅåñŽßÅOíäÕÿ¶Â7Å>Ÿö;ÎÁÓ΢mL;ÿåÜÅåmù6mùkÏ>ÿÁ#üðçö×Ö~)Xê¾?’Â]'GLµ›âW‰neKûKÍFyšåe¾d¸µe»µ m/™”›¯˜ÛÔlíÍóòôï×·NúhÒå“[«[ÏUÃúÒÏëŠç¼ñSAøâ_èþ¾7Z‚58ô}j#‘ýŽéìí¯V=Ρdͽí³îBËû͹ܬxOþ ð·Á^':¾‰yñq¯ Wâïâ׊ï!ÛdWOÃo–%h<¹Ä‚5 [æìíëueùþ},Ý£Ñõü?ÏËñ>»®á×Å- âÆŸ©]xôßA¤j·š%Û$‹Ê»´™ ¸(-¶DeÜ2§ŽkÈ|ÿÐøaàõ¥ðýßÅ—þ™.‘wöߊÞ)¾" YŒ&}Iü‰sâh¶H£!X9âeø$¯‚ÿg øöËTÔü}vþ4Õ5¬˜~$x‘Ö-:öøÜƪ$¾ýÕâªÆîèÞ-øgzu-Ä«yat`’>&û­²EW\ú0¼sEÿ‚b|-Ð<1¬é}çÅÓg®ˆÓMñkÅsN¾Lžby3¾¦dƒæûÆ&MÃålŽ+ý“à’ž øû#iÿ ¼e©øúîâ{u‰ôï‰$†6–Ô¹CbÂù^Æ2dmÑÛùJãhu`£nà’³¾çÕZþ»iá} ÷Sצö:t]\JT°Ž4RÌØ“€ ÀÕ‡´‹4ü=¼Žâm:ßUÓn„o¹¶ž5–)68 »‘Ôá€#8 ðoÁ-þëß5ÿèz‡Åmuw’ò9®~(ø¢yÒèÛIn…îQ34JK[ï19²1Œ_Ùïþ /à?…Ÿ±ïƒ~xÏSø‰vÚž&¡s¦|Jñ-–úÞÉm]­¤PI-íOÎVÖ2”ˆÁUÅÆÍT¿N[yß››î²·ëvýÏ>kü­Ë÷ëý/{蟌?¼;ðᎷã/‹ZŠéðí«^j “ x—m‘«;u*“] 9ëã_ÚûþÓàoŸ²ˆ¾|>Ö>!Ø_^ÁvtËcâ_‰õ xç¸ûZK¨?ڡŬ{a”I슦G-ézÏüCᆿà}ÃÚ•çÅ‘§xqîd³h>+x¦ –7 'Ÿs¤&¸v‰]Äc!6† ·kh¡ëß¾*h?<5±ñøéúuΧa£Ç(‚I·]_^CekØÕ˜o¸¹…7µwnbª  |‹ûWÁ#<ñëàï…<3áM[â ”ÞÕ´‰­¥¼ø—âWe·¡v²·ÛÙ®.1rÏ.é!cÇŒENçÅðL¯…Þ/Ò4+bóââÁáÛ#afm¾,øªÖFˆÍ$ÄÏ$ZšµÃï™ÿ{)w µ7lDU4åo¯3Kü6V~·þ´»¶—~Ÿõ} töüRоjµñ鳟ŚªèšRˆ$“íWm ÓˆòŠB~îÚfÜØ_—ÉôòOí9ÿ‘ðOÇ¿ü+»³Ôük€5K?´†ø“âX^}:ÞÊîÝV#ÿ{®c&ìâwQ iHb°ñwüûá_Ž5 {­vóâúËmem§ µø¹âËD1[ÂÆY!ÕYöF»¤ ¼¹Ý™Ù˜çÚ—7ó4½,¬þûþ].ÜÔSŸÙMÿ‹™¦½,“ÿ‡´}›[ø¥¡xwâ>ƒá-bôÅâÚÞ^i¶¾Döˆ­<Ÿ´7˜¢mûL1ïùsƒŽ‚¾Iøíÿ’ðWÆÿÚ×õmOÇðZÙXj–ú¼¿|Kc,’Ü-’ÀlÖÞýRÖ0-dó/-d% ‡*1è~0ÿ‚v|7ñÏÅY|g¯]|Q]jk¸ïY->'ø–ÎÃÌnÜXÁ¨¥²§È¹ŒF¹È99pmµÍýŸà)¤—»¿õýu=:çâÿ‡m>0Yø ãRUñmþ>¿‡“!/e ÐÁ$Þf݃\B»Kn;²‘Ò×ÇÞ ÿ‚@x7^ý¿,>1Ë«øìYC¢^Ãqf>!øgmJ}JÚñ,_lŠÌeV²]¶ä˜ÿtB.ßNðÇü¯á¿„~+Gã=ëâ‹kq^I~©sñ?Ä·Vk–-› u¶)óœFcؼaFu§þ'Í+I¥÷ÆÏñëhÌ´”’ÛKà)¿¹éøt»ôíâÿ‡|Qñ?Ä~ е%¸ñ/„­l¯5k! Šm"¼ó¾ÌÅÊ„mÿfŸ…bFÎq‘ž–¾=ýŸ¿àþ øûeøËâ~—«øîæÏU±Ò Ñ­n>"xŽòx%µKĜޛ‹÷‘°¹ËI¼Õˆ‡(qÏ¡xþ ›ð¿á§ˆ§á{Ï‹mtmnlȾø±â«ø|¹àx$ýÍÆ¦ñïÙ#m}»£m®…]Uƒvü?ŸÝç°-õÛú¿õÔõÿüTÐ~ x—Åz?„¯Ö£àN=ZˆÁ$cº{;kÕs¨Y3o{lû²þónw+Ð×Çÿ³ßüóÀÿ¾'|UÖµ [â-ÍŸµ6m.4øŸâw–ÚÆ]ÎÂe¹gÔ?{sæÃtÉpÅ剒'”‚?@ðŸü7á‚ôÍvÓD¼ø¶ÐøŽÃû6óí_Œ«?|y¥|,ð·â]}‹Dðå„ú¦¡qå<¿g·‚6–WØ€³mDc…œ`kåÙoþýà_ƒ²†‡ð÷Çz§Ä[»»{{/í9ô¿‰þ'µ…ç¶Y• ¦ÍAÖ.$Ì1ãb²± ëütÿ‚Pxâ7ì•âï†~Ô~#[ÿm[_Ía>£ñ3Ä×^]ôöMj†âWÔY­GÈZÕËÂ~bc%Žr«)Æœ¥y[O_¿õ׺½ÖÔ¡JU£?rú¿/ëËäöOhúµ¾¿¤ZßéNeµ½…'…ö•ÞŒ¡”à€FAšÄøÃñ{ÿþë~2øµ¨®‘á¿Úµæ¡xÐÉ0·‰q–Ù³·Q©5ãÿ‚c|9Ó¾èþÖo¾(½–ŸpºŒ’AñKÄñܵ×ÙãöÝ®¢'ò1+o¼D§,1&¸Û/þýà¿Ú/ö6Õ¾xWñæŸv¶w‘h÷:§ÄO^B“\¼Næø=ûµô¹]±Üy«NÅ]Íž‰¨©´¾ééý]%')B.Z7¿—õý>ÿa‘‘ÞŠä>|пgŸ‡ðxgáÔž —L·–I•µ¯_ë—e·6n¯çšvè¥ÈQÀW_RíШݭB¹„Ÿ4/þ¼ÕþÜOsca¬jZÍ, -ÞŸ{5Ê…p =´ªpÀ‚ uóçüGþHŠ¿ì¨ø÷ÿRÍVœUïéú¢¤­oï%÷©?ÐúŠ(©QEQEQEQEQEQEQEQEQEWñóö–ø{û+ø.?þÒž6ð·4)®Î+íwRŠÆ §`̱#JÃ{•Gm«“…cŒGo_ÿÁ[>-x/áGį>>ø¡'ÁO¶¯ªËá_éöwþÓ&9 Õ⺒0!ž9¶#¤‘8p–=ß4Ê\¶õKï×é}†ºé}åóþº­Ï«~|oðwíà;oüñNã/ ^I,Vú®‹}íœï˜ä 4LU¶º²œ¢ºšü¤ømñâßÂ_³ÏÃXüuã+?ƒß|CãïIâ_ˆ¾{Eñ5Ѻyìn`º»ißJ°¿škÉ7¤Â3-´pÁ)†d¯¢~ֺ炼%ðÇ_µÆox7áÇŒì7x;á÷|3á_x§Ãú?‰|jóÇ iW·ñAy­4eµ…˜4Å•˜ ;A×Q_ú÷íU¡ß~Ø?u_Ú«ãÆ»mñ?Iøï­Úxƒáþ±s†‘á+g­Zi…m*bVŠK"êI[í_n‘ƒKòy>½ÿóø‘£þÕÿ¶gÅÍ'Àß¶|_iðãÆV×^ðÆâ}2ñ5="+ 2k¹n˜[4·–’]ÝMh[vض0FY>p©~óO]|—#õvçé{¤Ú_ÝÉ¥ªÓïnkä½Í/g®Çé•ùû ~ÚŸ|uû_øVËãwôí/ÆWú·‰-ü}àY«¨èöÐZÞIl£ÃcDŠ="y"±1_æŽå%¤§M°ÿÁ8nÏxóWº×®~5j>?𧵿_Þè¾*>'†Îú²J—ú¶ƒ=¥¨ÐoóVÍ4/ûôW ™$T¨©ÁÔ{(¹tÚÒ~Ÿg}µ].Ö‘§)TTú·oÅ.žo¥ô]ìØZ+óþ­ûVk¿hTÓuoŠ?­õ?‡‘j—wšgŽfñ-…•ê]B²M©ÙOck'‡ï®ÿ&ž ÈÞáP§’LŸ§uÑV‹£dúßðm~—ÖϺOCTU/o/Å'úÛþQE‘aEPEPEPEPEPEPEPEPEPEP\—Çþý›>x‡Ç®§²ðß…ìÚûQži.dŠ%ÆJÅ.ç‘‚k­¯™à²ßò‹ÿö,Ïÿ¡-8«´‡6®}4àèh¦Ãþ©~‚I’Õ³<%à­ÀZdÖ^Ò´ýÎâòçP– +t‚9.ng{‹‰™Pd–ie•Û«;³I&¨üVñ†«à‡Úž¯àŸ ë7Õ,£W·Ðô»‹K{Í@—U+—“C oÞHƒ pIÀ?(~Ä·Æ/‹_.ø'ö"øãO ~Ï_¼5â+LÕ¬Zφ&›HX´÷š=V]ºœÉn’ŒÔÉ)1ŸÜ°#wMà¿Ûâ–¡û>è>$ºý›>*ê:õä±ÛM¤G­ø]/$‹ìÑÉý¡¼êËn!wv@‚A(e9WÂ’nkùyoÿo^ß–¿ð%bQqŒ%üÜÖÿ·mý+Oø*ÿHÑ_~Ú¿·—Æ_…ß³‡ˆü û>üOðþ·}¬é¶×&m_Âó¾‘ëVæ)‡öœˆíuÒGˆI°¸.bÆõõ_þÖ´_x{QÒ?f‹½þ±ï}¥ÛëÞK Ç1DK‡—XXœÊ€J¦ %X*ÙZ9•쯗›úþµ=òŠøöøý¿~2üðoÂ˯†_~"ØÜx§ÅžµÕõO J"[­HC>ŒÁõÿJ–5 ³ òWÏSç¡ W×¼iû[|OðÌZ+xö^ø³âÔôȯ®ÖÏ_ð´GI™ÃYÍç뇕«‹|dH¸rCi^}œ~iF_u¤¿áœ[‹ûÊ=җɶ¾ý?¦½úŠøoö¤ÿ‚…|jøgûR| ðç¿gHñeõàÔ솭ás'ˆ1¡Mwö8õ3äËkqÌŽÍ ?ÙœFó+ høƒûZ|Nð‡gÓrlWö*Ÿ»Œ¤ú_×ÞôL¨®wËý_ÖçÐtÙ"Iª° ŽFx=E|_û~Þß~&þÁÿ|gã/Ùïâ—Œ"xßÁŸ~'øOÅ:n…­É—:¯…îdðÏÙì<èuYÔjrÅ4FcåF&”ý™ÃC†M÷V”¥Óþùüµ½¬íT麳P[¿ëúïÓt}å®Í»FÜcã|Àùâ?Ûâ’|2ѵ˜eï‹wÚ¦¡<Ð\i1kþ[›8Ò8Y.dvÖ%&2Ȫ¨ìàÂûÕBþwûo~Ý_¾~ËZG‰¾üø—¢kº¦«§Cx²jÞšM Z´¶0NRxä{¸du¡óB”»DAdŠŸ»v×õÿri/kËn¿×õ÷ì}™HÊïqÏ5óÞ¿û`|SÒtçLý•~/êsêVÏ=ݬ!ðšI¥H³Ë†c&´¨îÉL M"m™`áÑ|çöÀýº~0ü)ñgÁK‡¿~%˜|[â(õxâÕ¼0Ísæé×óI£æmK帎Hbv•JÂD,s¯2’‹Š}ZÍ»}ßÒ»i:Præò‹—Ê*ïçý;$Úû)”67pr3Ú–¼ Ç¿µ§Äï Ï¥§†f‹'[ý2Þúáìuÿ Â4éäMÒYËö^2ÒÄ~VhÃÄOÜw×~ן·ïÆ_„?µßÁo |8øñPÐ|K©ßÅ~jžð”*hs] {VŸQ ÛÎ;H`Vû;„iC({K™Ûúþ¼ÌÛ·ÝsíÊL ÙÀÉã5àúÿí]ñ3IøŠº6—û2üUÕ4£<1v {à f¨á ÉåÉ«¬ûcÜÁ‡•“°í 'ǼMû}üdÓ?৺GÃm?à_ÄI¼7…5+¦…uO ·4Zµ•´zÔnÚ˜¶© ²fdœùëþŽH%8º“5¼¹­ÿnÅÉß俤›JR匧Ñ[ñi~oúm'öÖsŽOz+¬ÿjŸ‰7—÷³WÅH4&Õÿ³ÏŠ\ðÉÓÖßÎòþÜa±ºòv~÷`‡ÍÛÇ—»å¯'øWûvü`ñwü7Äþñ/Ào‰ºo…-ü9áùÖSà š¸¿Ö"›U™áÔšY`™-¡QfYìN|”. Š+žÖëýkÛççÙ–âÔe.‘µþnß×ù´ŸÙ›FIÀÉ4œÏ^:×ÏÞý¯>)xƒÄæÇ[ý–~.hvb+‰?´.üAáI!-Nñ¦Øu—“2º$Jvà4Š\ª†aæ?²wíãñ‹â—ÇÚ?¾|O‹Nð¾¿åi±Mªø\aðîxšd§™f¸¸•äIs,köèÖIcTu‰Gߺ]þJߎ»|·i:äwùÛúòóØû<(Rv€3É÷¥¯ðWímñ?ÄñëGIJ÷ÅŸ7L–úÑouÿ JuYÑ-œ>F±&É\3ÒìŒ;œóOØöçøÁñÂ.¾$üø•4þñˆ£Ó]õ_ ¨¹º“C‹Ré1Ç”2Ê$ÀçÏ|«4ó.gÑrù&—߮߫W\¯“Ÿ§2ͦþí?¤¾É¢¾|Ñ¿kߊzŸ†5›íCöXø»§Þi¢k§Íâ 4ú®ù6¸…“Yh×Ë_¼×LŽqâ¼çöý¹þ0|Zý†üø£êšßˆ¼= [UðÄÍ¥,þ"µ³“M˜6¤èÒÞ[±$‡zGöÈÙå…‘Ì^âÚë⎅¤hW?ì·ñsYŸU²77–¶Þ ðªI£Ê&’1o9—YUw)Kº#"m™FíáÕN]ìÜ~i_îóÿ5{å…ÿ¯=vßîgÐ4WÆŸ¶íÓñ‡áO‹> [ü=ø ñ,ÃâßÙG«Ç­á†kŸ7N¿šM3j_-ÄrC´ªV!`³œ…EñwíƒñSÃÚ…¼:ì©ñ]Šk+k—ž×Ä>!–XRI-ØM¬£…Ù¢f¡hØ£:fˆÉM6º7šIýÚþ»4Û”\oÖ*_&Ü~û¯é¦—ÐÔWÆ¿´7íÑñ‡á¿íÇà_xà/ĽwÃ7ÚN¹<±ÙjÞEñ#ºqŽ{v¹Ô’H’ÜÜL®²KWjÊSÕüaûRüHðïÅYt ömø£¯h±ÝÇn¾$´×<5„±¶ÝÓˆ§Õ’ä"nlƒc°áO ùÚKúÿ/™3"æg¹Ñ_ø›öûøÉ¦ÁOt†ÚÀ¿ˆ“x2o jWM êžnhµk+hõ¨Ýµ1mRdÌ,É9ó×ýJ{?†?jo‰çÅhô cölø££èy%³x’ç\ðÓØ$J[mÁŠ-YîJ>ÐBˆwÃ*9Ã^ô!S¤¯oûvN.ÿ5ý4ÒR÷e(¿³oÅ'ù?é4ß¹Ñ_~Í?·çÆOŠ_ðP‰>ñ÷À¯ˆº'…´+ÃóAÞ©á§o 5ÄzƒKqtöú‹¼Ép`…QbiÙ<¦Ü±gæõ¿~×?<[âgâÙsâ߆-E­Ìâúû_ð¬Ð™#䎶úÄ’o•ÑaS·hi»"um[î¿áéuÙÕòÿZŸ@Q_~ËŸ·ÇÆ_‰¾8i~5ýŸ>)=…uÿ+L¶“Vð²/‡´ë´Ó$hõ<Ë5ÄóI*K™#_¶Æ¯,abõ_ þ×? ý°~)j³îƒâK¯Ù³â®£¯^K´ÚDzß…ÒòH¾ÍŸÚά¶âwd$†S˜ÕpOšÿÁCoÏŒ¿`øçá¿ÀŸˆÞñLZeì¾}æ©á«‘áF‰âX®.Ðj2¤É(‘ʬ pÃË;Õr¹ÞPq›ƒÝ;_×â™ËN~Ö1’ûGÛtW!ð7â&»ñGáõ¾¯ñÀ¾ øsªK,ˆú.µwauw©ÂÈd°¹¸€‡€$$ ëêZ¶…FJJè*ž‡áÝ?Ãooá«=>ÞYæºx­¡XQæšF–Y ¨»ÈîìÝY™˜ä’jåx·ìñ]ø¡ðoÄ:‡Ä-N}ZúÏâŒt˜f•Z;K?ê6¶Ð€Š#‚£Œ€’NInå4Ôyº]/›ýí ¡”†ƒÁ½UЉcgfúÁ»»h!XÍÔÅUL²{•D]Ç' £°«”Q@ô/Øx_M[? XÙéÖhï"Ák ó»;°Ue™‰îX“É«l¡”†ƒÁ½xü+â§Žþ þÍ“x‹övÕ<1¥x†oH°ó5ímVÑ¡¼Ô-ì›÷0Ý[°e7K o3»+›rùŸ‡¿oýoöaÖ>(x_þ u£jZ¿Ãèô-CJÖ|áûÔ.¶Ö®.-,mmô:êu¿7–Wy),ªÁ¢pÊ „QýãqëÛ½ì´îÝöÝ—É+&µ¿áëø}èúÃ@ðý‡„ô+=/ÂÖVšf™§@–Ö––¬0ZÄŠ#Ž5QT€F¿ Xx¯C¼ÒüQei©išŒmwiu ÍÔN¥^9#`UÕ”T‚$ùÖïþ £ðëNðT—Ú®ãû?ÅâÈ| ÞŸAxõá¬Ígöè­|¢ÞNÓý Oçy%?å¦ï–¹ŽŸðV‹?†Ÿ³÷†|y௅_µ¯xâÛÁw:mΊmn´©Ž±™?ž¡›l…¦!FVwUPÊpw»^m~6·þ•“O©.ðÕé¥þëÿò2ûŸcëÅPŠ : ©®ø~ÃÅkYøšÆÏQ³wI ¨Vhّã`FUÕXÅAŠùûö¸ýµ5ƒÿ±½ïÄO è>)ð½ÛÛÍ7Ú5¿ O©'†£…˜ËsªYAq‹—Ë ÆäcÆEkþÓ_ðP þË|!àŸx[âGˆ|CãËk‰ô(¼7á¹u8ïÚÜnš1ØäDćÌ*¡wuÁ/wWÞß=Å¢ú~‡»U=WÃöì¶o­ØÙÞ>p.íxVCm0VQ$eØá]Æáƒ†#¹¯¾ ÿÁT~x àÿ…> ÛèŸ|AàoxY¼huÝ'ÃsOg¤iJ±³ÍxÌTÆê²†6è|#‘ MAñ—þ EÃÚ?ÀÞ ð¯Ãoˆ^3Ñ|e _kÑëz”×QL¥“Ä-W L¬·‡y%vƒ ¿åž¾vù«þ©üÓìR‹–‹ªoåeÁ«ú®èúr©ßø~ÃTÔ¬o5;;›Í1ÞK9å…^KFt(Í”%”•ÆCÐ׋|sý¬.>þÑ| ž­¥[xóXsß^xvk«+íú}üëc Üs*ÚÝ«Z XÈŽ¾\l nu"¿Ç¯ø)ÃÏÙÛâ­ xÚÛÆÑxRÖÖûŚƕ¡O{¥x6Þä‘ ºÊ D¥TÈÁ´Q6Q_= Þv]íóþ™ ÛîOäî—ä{íSØI¯Gª½›j‘[µ¢^TÜ$,ÊÍ“‚Db¹Á*a_8Gÿ^øp¿õjšÄ­>ûÃÞ'±ðŽ«©Ýx^tÒ4ëûö‰tõ’ó”)tn-ü¶MØF\ u'éº#ïET[wù'ù5òk¸Û³å×ô×àNéöÚýΫocg©yV³Þ,*.'†&‘£äs"4ÓRp¦G#Ž~YÐnêßðVÍ[áØið«-<<Út:Ÿ–â÷þ¸¡µÔ¥´.[kFt»øe.CE'ýžíµ+¿†þ=ñ·áÍOYÕ<{ †¬öuíÃO¥k :DËöb-­¬êdx¤+pýç//[ü¬Ú×ÖÚy4ö >NnnŸŽ‰éýt>Ûªzg‡tý÷P¹Ñìlí.uiÅÕô°Â±½ä¢4ˆI+™GI¹²vÆ«Ñ@iðTy>(þÖ¾Ó>éþ Õ~ø£D×/¢žÝÄþ&:|^`¹Ñu'¸Xî#vhÑ"6àÊK†6S]ŸÀßø+7ÃoÚ½Ì~ðÿÅ=?HÒî5K__Õ¼{c¢hWzrÌ×v÷—ξTO·“-“ìF\HBT©&¹¯Ñ·èžþš|´NÏAÙór­ïoWkÙyÿ“{j}=TôØxv)ÓÃö6v)uq%ÜËo Ä&šF-$Œ ÎÌIf<’rkçoÿÁW>øÏHÖõ~ßÇ>Ót¯]|@¶ºñ'†®¬[ðý¶Ó>£d¥KȈ$„˜™Rp&ˆùXu&O ÿÁPü¬ø;Ç>!ñχ~"øCð…#ñ¶¡{â ¢ŽçINV{o%å3ZÊL@ å  œUJ.æVÓðÖÿúKºïÙ’š’VwMéçµ­ÿÇ^Ò]ÑôTÐ|?aá]ßN𽕦›§Ù Ž [XV`Qü(ŠQìy_ìÝûdi?´§Œ|E iÞñÿ„u_ YXêSÅâM%lÖæÞðÜ$·–9dIAû,›€l¯€9×èjÛ‚iì2êÖ+ëi!½&†e)$n¡•ÔŒAà‚8ÅE¤é6š•ma¡[[ÙXÙD[ÛÁŽ(#@Q@   UŠ) §¯ø~ÃÅZ5Îâ‹=KO¼Cö·P¬ÐΧªº0*ÃØŠ¹EO\ðîŸâ{$¶ñ-ž£mðÝ,W0¬È²Ã"ËX$DunªÊ¬0@5rŠ(ž«áû v[7ÖìlïN¸v<+!¶˜+(’2Àìp®ãpÁÃÜÕÊ(  w^°¾Öm5Û9µ ’;[§…Zke“o˜±¹@Ûpgjç «”Q@ßÃökÑê¯cfÚ¤Víh—†7 2³D$Æà…‘®pJƒØUÊ(£È v¾°±Önõ+8u A#Žêé!UšåcÝ嬎ç ½ö‚N76:š¹EOLðÞê:=¥Î­8º¾–V7¼”F‘ %`3#ˆâ‰76NØÕz(åP=ú†,ÞßÃV6z}¼³Ítñ[B°£Í4,²Pw‘ÝÙº³31É$ÕÊ(  š‡ì<+£[éÞ²´Ótû4Ákk à ?…@ =€§êÚM®¿¥\Øë¶Ö÷¶7±4óÆ$ŠxØdt`C)‚ÁbŠM&¬Æ›NèŽÖÖ+h᲎8a…BG(UE81UõÿØx«F¹Ó¼Qcg©i÷ˆcžÖêšÔõWFX{W+Áà¨[ÍGÆž'ñ FÊW’1m©k—×öêÅÑHCuq‚†˜ÇÕkžøgñSAøÃáû­SáÝñÔ,lµMCEšCì»±¼šÊê=²*“²âÞdÜÖÛ¹K)´Ú½Šwå·K¯¾Î߃Ò:)ÄhYø 2káGÅ ãÃøÏáéÔ¼7â½6ßWÒîÌ2@nmgeŠO.UWMÈêv²†ÁÒÞÿÖû~OîÐQY|y¥|,ð·â]}‹Dðå„ú¦¡qå<¿g·‚6–WØ€³mDc…œ`jö«[ëúE­þ”æ[[ØRx_i]èÊNdÁ¡;Ý.–üoo¾ÎÞŒm4“}oo;ZÿuÕýWrÍÏüOø¥¡|ð|šÿÄ{Ó§éQ]ZÙ´Â &Ä·71[@»#Vošiâ\ãvN$t\,íp¢¹¯‰ßü;ðoOÒnþ$êK¦A®kZ‹d“Ͻ¼™`·‡¤ò:®ã…É s]- U̶½¾vNÞ¶iú5Ü[;uß媿ޟÜŠæ¼_ñþñÇ„ü7âÍIm5¯Ý\Yè–ÆßK´—R¨eR©¶d|¹PvàdK@\(®{Tø© èßô_êWÆ?ø‡L¾Ö,-<‰žÖÎKX®dóì]h6³o3*V+ÐÑÑ?ë·ç Ïiß4Wâ®¯à› âþ&д»-júÏÈm/%º†ÞO0®Æß%…ØÚ¬Y|¼°”·C@=Ÿõ×ò +Ÿð¯Å- ƾ0ñ>ƒá«Ósªø6ê =^"Dû$³[Gsïe ù†h›(X Ø8 ÐPöMnW5ð÷âÿ‡~*ê'µð¤º…ǃµ‡Ð5…ÉØïRghIuñÌ-¹r¿>3@éhèŸtšóM]?Fµ]л®×_5£_'£<ƒöäý|MûSü“Áÿ ¼c¥xQ—WÓu6Ôõ µ¸¶Ù^Ex± uº¶?<¶ñÞg ¼’|/â‡üü~ÒŸ þ"CûX|A‡Æ?~!_èײë°xbmN‹F¸{6Æ=y®[5’k“4SÍ#Oö©‘–#ú»á'Åÿüuð<>$øU©.­¢ÏuwgÊÃ$A¥µ¹–ÖuÛ"«|³A*g;r2'¤w¡gà(É©iBíé×î³^–²z~¬µRM(§§ù÷ïóò쀢ÿ‚'êZWÀ›¯ x7Æ|?s«øÎÛž•§|°ƒÁz¥­½„¶‹¦O ‹½ÓÄï"NòOu+ù‰˜ÌXO/¿ðßüÆóñ׽#Çšu†¶\Ëe«O¨|1ˆëÁáXáŽÙV1#eã‘ËbEŽ?­ ™naI!;’E §È<ŠÁøŸñKBø5àù5ÿˆ÷§OÒ¢ºµ³i„M‰nnb¶vF¬ß4ÓĹÆìœHR~ï$¶íò·åÓç¹PnI(ëÕßñïúžúŸü/^ñÁÿ‡þñ÷ņþ3x(ø ¼Qðš=fÒÊÌJÍþ—eq©´V:žÆòäº>rH"ƒ÷J#Ã{Ÿ‹`?Šº§Â_…Vž øÙ¡ø{âÃ]Rð»xš´¶×º}äPþÔ·[ÞD¶–l“™åC$nZ®>µ®Ç?´/†Ú‡‡-|gzlçñfªº&”¢ $ûUÛC4â<¢Ÿ»¶™·6åÆr@)´ÓƒÚM|Ýݾ÷'§[•Í&ÔúÅ={++ü’Š¿k\ùëö¨ý‰¾-ükñ‡Â›Ï„ß|-á½7á5õ¶µcˆ< 7ˆ/õ-J+Ëžêê=ZÔ4rC|䯱+ w˜AÚ(~ÑÿðM|kñOÄü ñfOx7ãm…®Ÿñ'G‹ÃqÝÜêÂ+u³–].ñç_ìé.,Ñ-¤2Gt"4b7ÛëJæ¼_ñþñÇ„ü7âÍIm5¯Ý\Yè–ÆßK´—R¨eR©¶d|¹Pvàd û\ÝoÍóëuÕh´ÛE¦ˆ„ù³µ’_$î¿o¾¯]Yñ÷ÅOø%¯Å߈ß°~8ø H²ñ·Ä} â¼MðÂ{‰4çÑþÂ,íOíµó×n‘§}¨X¬ä*ùª"û’0Â5ÎÌ@À'ØgŠusW?ü;iñ‚ÏÀW’¯‹oôyõø,<™ {(f† &ó6ì’âÚ[qÝ‚7²¦½m×Hëç¤c¯’¸—¾úY~:~.ËÍØøÏÃÿðFÏi´–›ñ’ûâg„.~)Ú|N¹ñÍÆ¾¾š9.t©ôÓ¦¾„ûX…A.2Ç)c;>k¶ðJ?‰^ø™ðˆxsãÆ–ß ¾ xŠïVð÷…u‹«Ù¬î­îm$²ºÔÓPŒÈbµ½¹† –(L©pʾä®{Nø© ê¿uØ_ñ6…¥ÙkWÖ~D€Ciy-Ô6òy…v6ù,.ÆÕbËåå€ ¥¦1´c ÔRI=tI+kÒÉoæ÷nöäß4»Þÿ7'ò»›ûÒ[+|uàø%÷Æ¿„^(ø]ÂÚ'ÃQø7àžŸy¢ø?EÖ¾5üÉc4+o ßÝC«[ýªkx!IR8A]ÅÕ‹W þÊŸðO¯ü-ý›>"ü'ý¨üáω^øƒ.µ,‘é—×ÿÛ7w·ZŠ<¨ÝyŠÏ~ËÑPdÈNGÔµÏx7⦃ñľ+Ñü%|nµjqèúÔF #ûÓÙÛ^¬{BÉ›{ÛgÜ…—÷›s¹Xÿxœ^·Ný[Z^ïw­µz뾡85(èÓM[K5µ¬|Iû8Á[ökðÿŒ->øÓáÿ‡õOÀ:€ô-sŸ ¬<=¬À.„a5Zö ÚMFî/"<Ÿ±Äì$vs)ŽÿÁ¯ø#¦¿ð—Áí4?‰> ð¾¹ãïMá k¿|9‹ÂÖ\I“ýµ¨iÑ_Iþ 1"›uÚÒ(Påû¶¹ÿ‡_´/‹~¥uàÓ}‘ªÞh—l`’/*îÒf‚âƒá-bôÅâÚÞ^i¶¾Döˆ­<Ÿ´7˜¢mûL1ïùsƒŽ‚‹Üh(®jçâÿ‡m>0Yø ãRUñmþ>¿‡“!/e ÐÁ$Þf݃\B»Kn;²‘ÒÑÑK£ÛäÚsMz¦…}Zê¿Êÿ“OÑ…Íhü;â‰þ#ðf…©-lj|%key«YdSiçöf.T#oû4ü+6sŒŒô´lEsÞ ø© ü@ñ/Šô _­GÁœz>µ‚HþÇtöv׫çP²fÞöÙ÷!eýæÜîV¡£úûÀ(®{áŸÅMã‡îµO‡wÇP±²Õ5 i C²îÆòk+¨öȪNË‹y“på,¤ÐÐôÜ6mÏü*ø¥¡|løs£x·áéÔ´Z­å…Ñ‚H|ø›î¶É]sèÀ³ñÇšWÂÏk~'ñÕר´OXOªjSËö{x#ie}ˆ 6ÔF8PIÆ&¦RŒbäÞ…Fœ”"µz[­ûõãÿ·÷À cö¨ýŒ~#|;øq§Zk^.ÑäÓìæ¿wKhäb22+0^;)úW«èúµ¾¿¤ZßéNeµ½…'…ö•ÞŒ¡”à€FAšÄøÃñ{ÿþë~2øµ¨®‘á¿Úµæ¡xÐÉ0·‰q–Ù³·Q©5¥œekjDd¤”¢ô:4]¨ì1K@9è©¶‡=ñ[ᆕñŸáö§á>±—«F±Ü6—«Ýé7€W]Ýœ±OÊŽcu$d æ_ÙOþ ீÿ <_áÿ꿯%ñn±¬Í4–Xøéÿ ðÄoÙ+Åß ü¨üF·þÚ¶¿šÂ}Gâg‰®¼»éìšÕ į¨<³Zµ«—„üÄÆKîxgþ ðçNø£øY¾ø¢öZ}Âê2IÅ/Çr×_gŽÛvºˆŸÈÄ`­¾ñœ°@Äšú.Š•œŸóZÿöîß×’ìɵü¼Öÿ·­Ëñ}ÙòíGÿ‚ð7ÆÏÙûNðoƒµ?ˆV“hÚ•¥åœº‡ÄßΦ5Ô­nîìoÙ§r–î"iw˜\«FPŒ@ñ/ü[á‹ïOøƒÿÕøcñ;ƳøƒÅŸSQ¹XUÆŸñ[Å:u°D‘&Û{mI"S¶5ÜBÍ–l³1>ùEW´’jIê _sä‹_ðI|Vý´t?‰ú–«ãø¬"Òµ˜µ[[‰>%´–Kë»:XÑ`¾Tµ¶U´ºA——‡1·–¥=ÿþ ÏðÛRøºþ7º»ø§ýºú¨ÖŠ'Å&Ÿö/›`ºˆµoê^Vß—fß–½ÖŠ˜¾XÆ+hÞÞWwþ½bå';óußÏ×¾ïï>GøkÿðgßÛ_Yø¥cªøþK t=2Öo‰^%¹•/í/5æk•–ù’âÕ–îÔ%´¾dJRlF¾coï|ÿØøeðÏÇ0x‹ÃR¶ó‚-ÿÅ_j¿½ã}Ö×:“Âß,·(vœ2á”ïtR²åPè¿P”ÜääÞ®×ù+/ë»}Ï’¿f¿ø$§‚ÿg¿ÚÇÞ4±Ôü}q¿{ Ú<3|Hñ%á†쨬f±Ü_2]I¹ehä—ÌhÔǰ§–{oÿÁ3þ|<¸Ôåðåßŧ}[M¸Òn>Ûñ_Å7ÀA:lÆ.57K»4{dCÊ2žkß褕¿/—oMX¤ù÷òü6üŽ?eø#Ÿ‚gýâÝÖ±¬xúö/ˆzõåÕ ƒâ?‰CÛi÷–q™šÿ/xÚCö̙”Q( ôŸÁ4~xWºþ¤Þ|Z6^%ޝZŠþ)¸¸U†e™<‹‰53-±Þ£sBÈ]rŒJ’§ß¨ª¾‘]¢£òвþº¶ßRZ½üÛ6ïÿ Ù$º~ÆßðGÏ~γ.©à/êþ;Ô'×ï®æÔ.4߈~#µO)µ[‹ëam¶ùZÒ@²Ä²¼[LÂC!“{ôOø&_à 7áî±á›Ï‹GNÖîmîî_‹*–ådeXü«§ÔÌЦ'“zFê²a †(›}“â‡Å? |ð§â¯Œ:þá h±y÷ú¦©v–––‰¡¤–Br̪2y$ÉÎþϵwÃ?ÚÛÂ÷š×ìÅãÏ x÷JÓî>Éws¡êQ^¥¬ÛCyrylv1R Œ‚â¦OÚ)Bý5ô¾ŸŠÓÍ›ƒæîßÍõü?Àfø#ÿ¾þÈ>øsñVø{¨éZv˜5{+âŠ,àšúÖÑ f´òõkkbe˜‹x„qÝ“cM¶ißø$—‚~/þÆÞ.øeðÿTø‡gy©iÚ¯ö5Ωñ3Ä×QÃwf-Õ¯ïÞK›U1ÄM´¾dC÷„G™Ö7wØ@e¾–8c)y*‚Hdú’÷5ã¯h¿ |ªx‹â6­§hZ‡k%ßÜ-½­Œ©g–Y\…DU–$]JŽnR“ß•¿++v²ìU9ºsRŽëúüz÷<8ÿÁ1>Üü7Ò<1{ñhØh÷^Dñ|XñTW-,É I¾åu14‘âÞ=±»²FK”U.å¸ïÚ¯þ àŸŽß³ÆàŸ ê~?´“÷ö·|×ß|K 1 RÞöä\?Û™îd+‚'›ÌhX¡ŒÇµJýioqÜ -«¤‘J¡ÑÔå\AA§ÔÍs»ËéÀ"œ¹y^Û~ðOžµÿø&ÂÏé5ާyñ|A Û=¥¡ƒâç‹ ‘£yåœùÒGª¸}ó>$”»…Ø€„DUã¿iÏø$‚~=ø‡á]Ýž§ãûXüªYý¤7ÄŸÂóéÖöWv걯ø»Ýs7gº‰JCß[QIÅI¦ú4þißþºmu)M«Ûªqù5gÿ³³èxàšŸ ~$Ï¥Éâk¿‹Ú>™o¤[ý‡â¯Š,AlŒÊ-õ$K½<›¥òîÇšó¯ÚsþûàÏÚ#ö•øiã«_Ç–¶þ½¹—Y·Oˆž$·’æÒd±€Xù7ê¶ròšI!òÚUó<Æ1Ã}…ERvÕW'ü­ò<_ÿ‚o|3ñ/ÄUñN©wñTj«<7`ø§â{{=ñ þ‡¤°ýÚî_/É`Kù¿ˆ?à ׿oËŒrêþ;Pè—°ÜYˆ~#YÛRŸR¶¼G‹Û"³U¬—m¹&?Ý‹·ì(„œ'ÇxÞß4âÿ÷¤÷HN*Q”ZÑÚÿ'ëɵÔð«?ø'?Ãk‹Ëã‹{¿ŠŸÛÉ«ÿm„oŠ>&}?íwƒ§DÚ˜wÿ˹‹ÊÛòlÛòמ|5ÿ‚Gø3áÏí¯¬üR±Õ|%„ºN™k7įÜÊ—ö—šŒó5ÊË|ÉqjËwjÚ_2%)6#_1·ýqEnåé·—§Ü¾åا&ã(½¥küÿ¯&ûŸ>øOþ ð·Á^':¾‰yñq¯ Wâïâ׊ï!ÛdWOÃo–%h<¹Ä‚?®è¥röê­ò×Ý~ãç“wo[ßçÜðÁ4>x=i|?wñeÆ¿¦K¤]ý·â·Šoˆ‚VFc ŸR"\Ƹš-’(ÈVŽxŸÙCþ +à¿ÙãÃ~=²Õ5?]¿5Mk&‰$u‹N½¾71ª‰/¿uxª±‡»³o>iÞž´¢—*ærîœ~Mßúõ}Øs>^N—Rù¤ÒüÿÙ>h¿ðLO…º†5#O¼øºlõѺi¾-x®i×É“ÌO&wÔÌ|ßxÄɸ|­‘Åq¿²oüSÁ_ÿdm?á·Œµ?]ÜOcc±>ñ#ÄÆÒÚ—(lX_+ØÆLº;)\m¬cëZ(²bRi4›R#WVÑT›Jkù¹oÿnÞߟà»"Z^ï•íóµÿ/Å÷gÆ¿µ÷ü§Àß?d|6ø}¬|C°¾½‚ìé—:ÇÄ¿êñÏp ö´—PµC‹XöÃ(’4%ÙLŽ[ÒõŸø&‡Ã Àú‡µ+Ï‹#NðãÜÉfÐ|VñL,nO>æ=HMp3í»ˆÆBm A÷ú(roq½l|‹ûWÁ#<ñëàï…<3áM[â ”ÞÕ´‰­¥¼ø—âWe·¡v²·ÛÙ®.1rÏ.é!cÇŒENçÅðL¯…Þ/Ò4+bóââÁáÛ#afm¾,øªÖFˆÍ$ÄÏ$ZšµÃï™ÿ{)w µ7lDUúŠ9›M>¯›æúÿ]ßr¹Ÿáo—oÁ}ÇÉ?´çüGÁ?üCð®îÏSñý¬~Õ,þÒâO‰ayôë{+»uXŒWü]›³‰ÝD¥!ˆnÃÅßðKï…~8Ô-îµÛÏ‹ë-µ•¶ž‚×âç‹-Åo Cd‡TUgÙî‚ò6çvgfcëÿ~/hŸ 5O ÙøÆyáŸÆzÒhXŽ”KvÖóÜr ˆ×˵˜îl €3’éê`’NßÌÛõ²¿ágó¿QÎR¼o§º’ÿ4­ò½×ÊÝ’~;Á$¼ñ¿öµðÇÄm[Sñü¶V¥¾¯¯ÄŸØË$· d°5·¿TµŒ Y<Ä‹ËY BáÊŒzŒ?àŸ üsñV_ë×_WZšî;ÖKO‰þ%³°ó#Û·0j)l©ò.c…nrN}Ί"¹,ãÓo/O¸™>uË-¼Aÿ€ðn½û~X|c—Wñز‡D½†âÌ|CñÎÚ”ú•µâøñ§áo‹üMr$:Nâ‹+ËÙ•.Rå.Û@$àp'N? iÇìÞÞI·'øþ -’õ机Úý´V_×vû³È?gïø#ÿƒ>þÙ~2øŸ¥êþ;¹³Õltˆ4k[ˆž#¼ž mRñ'7¦âýÅäl.còÒo5b!ÊÜsè^ÿ‚fü/øiâ©ø^óâÛ][›2/¾,xªþ.x ?sq©¼{öHÛ_nèÛk¡WUaôró|nðu¿Æ~Üx§Ãéã»,ëqxy¯âœ–"Cº[mÞa‡Ì<ÌmÈ#9§Ìöò·ÊÚþùìùºé¯åÿùŸö{ÿ‚>xà×Ä֡«|E¹³ñ¶¦Í¥ÆŸüNòÛXË¢ÙØL·,ú‡ïn|Øn™.¼±#BDòGèÿ‚fü/ð^™®Úh—ŸÚØfÞ}«âÇŠ®Ýaó£›0<Ú›5¼›áOÞÄRM»Óv×uoV·øç໿Œsü<¶ñg‡dñí®˜5™¼:º„GTŠÄ¸Œ\µ¶ï0E½•wíÛ’y­|Hð÷ÄË]B‡z擮äê7EóØ]%ÂÚ^[¹Ž{iJ²XÜd8e# wrKÒß%}ÆåÊﳿãk¯•ýò÷ì§ÿ‰ðWÀ…ž/ðÿŠu_ˆW’ø·XÖfšK?‰ž&EŽÂçZ—PµHÉ¿S ÊÇöe–â-²ÊÂmòH%¿{¡Á4¾xwÁZï‡ôÛ¿‹'OñÛ=ãOñ_Å3Ý)·vxü‹™5#5¸Ë¶á  `>àýEL½ô“ôûɶßvßÍïýv>Aý–ÿàÞø1û(h|wª|E»»··²þÓŸKøŸâ{X^{e™PÚlÔ­a"âLÃŽ6! +Ю¿ÇOø%€~#~É^.øgàýGâ5¿öÕµüÖê?]ÿ‚¿^Úè_²­xœÐ<5ñ ÁzÞ·;ÿ©²Ó­|K¦Ïsq7Åo#±*¡cÀ$|sû`þÓš3ë‘|~ý˜>4Ýx[ãWÄoüøoâo jš£Õ’Hçÿ‰…¤ºÄGPŽ_ÚØ,1\‹Œ0†I&S#y#õ/Û ö°øcü#ÇÞ-øuñãÅÚmŽ”Õþ3~Ï?.Ÿöд}WWøC&£«Ïÿ 溎°Iuý¯ÜsßÄѺ.ha‹³üÅJ§ë×ì§ã[‰³ïjöþ ´»Öü3§_M»‘ªFòZÆì.ãÉÙ>Xï\œ6Fk½d ÷€?QKU%µn÷ùÉÛÿ&·¢Kd’rNRRì­o”WþÛ›ëvÊ(¢ aEPEPEPEPEPEPEPEP€~Ü?òP¿g_û*–ÿúeÕëßë3Ä^ Ñü_u¥Oâ½/OԦЯF¥¦Éun’µ…ÐŽH„ð–Ç ŽiSzàí‘ÆpÇ:u4ãȤ»É¿ü–1ÿÛK«%RPk¤T~éN_ûrû‚Š(ª F`ªKä“Ú¿3¿`‡º‡í㧈<ñ?án©ðŸá—Çoø²ÞËAÑžïÄ2Ý oSšÚ)53xb·ŠU½K‚b· -¼±Ç»dŽÏúeE8· s­ÖÞM4Óù5 äù©º}þŽ2‹_5&~:þÉÿðSOZ~Ù>?4öÒüy‰4çðgŠü|5[k&vm"ÏRÓ¿³­­ô Ÿ1Ñ,⹑¥ ŒHÑ´£à?íogqûV|ñ‹ñË^ø§ñ×Rø5ãõ? øšh`]#Æ2 .eÒ!°H`W =¼ðwˆìãlZIh€Idõ÷¥p:õ÷¬ù?wÈž¶µú¥i-Fùµßá­cITN£šŠµù¬õ[¦—Gen^ò½î­øýû-~Ôÿ 5ø(ÇÃÉüKûQxÆÚµÿÀ¿Þø—R·°“Ã:›\éwWI,.t‘Z^I%‘æÙ,™æi; ÿà Ÿ-ÿàšÿµli{ï|=¹Öõ_ ë¶¾+²—WÚ#´÷3"âh羑 Pù¦CY~¨8g“ïKZÎ\ú5eË(ÙinjžÑ5Û—á^Wîcìù-¯,¢õÖö‡#Oü[¿;~4ÿ‚‘_ iíà—í.ßo¼#ð£Ã>4Òµ«ÝgNԯ⼺¸»‡S–Ĭk –…´·Ž†(什…Ä¡O¾ÿÁ¾*[þÑþ&øŸã­'ãg‹üm¥-úiúƒµ¯hÞ$»ðö”`·1ϨǥÉ2Cs%ÜZüö-På™~O°?i¯ÙÓGý©¾Oá?_ë:B ë-ZÇSÒfŽ+í*úÊê+»K¨ ©$Eâžœ,±Émã) ò³çìm'Áߊڧ~&|Hñ×ÅOêZTz z§ˆâÓ-FŸ`“4ÞDúe•¬#tŒÑÜ•PŠpiÔu%½šò]š]þËNÉGÞM¿t‰Aªj1ÕÝ~—¿Üå¥ï+E¤¯#Ú袊ƒ@¯™à²ßò‹ÿö,Ïÿ¡-}5Yž3ðVñ·ÚÄ +N×4]R#å…ýº\[]Fz¤‘¸*ÃØŠiÙÜiÙÜчýRý:Š)••Ž{â·Œ5_ü>ÔõøWXñ¾©e½¾‡¥ÜZ[Þjº©X会€K~òDS‚NùCö#ý¼~1|Zø1ãm[âÀ/‰ú¾£ ø—Ävú{.«áx[P[ÜÚE¥ÄSEY­-Ç–ò˲9>Ç!YegC/ÚOCðîŸá‹7·ðÕžŸo,ó]ŒÁõÿJ–5 ³ òWÏSç¡ W×¼iû[|OðÌZ+xö^ø³âÔôȯ®ÖÏ_ð´GI™ÃYÍç뇕«‹|dH¸rCîZχìL¶·ÈìУý™Äo2²öˆ?µ§ÄïxÖ}3Âÿ³ÅŸiÑ,,š¶Ÿ¯xZi‹ÄŽáRçXŠPcfhÛ(hÉRÊU¸_ø~ÃTÔ¬o5;;›Í1ÞK9å…^KFt(Í”%”•ÆCÐÕÊ®etíý~ÂÇÆ_¿nÏŒÿ‚ƒxKÀÞøñ3Wð­×‡¼E;CkªxaÄmmy£Ç¥Ï©$±C\Ì­†íˆ|§ØL~±ûTüI´øºþµýš¾)ÜèKª‹ât×|24ö·óv}¸BÚ°ºò¶þóa‡ÍÛÇ—»å¯iŸÃº}Ö½mªÜØÙɪYA-­½ãB¦â¥hÚHÒB7*;C e cBs´båL]£½Õïçw}}õk%sjW²µÿOø7ÛÔøËá_íÛñƒÅßðPßøÄ¿¾&é¾·ðç‡çXn5O 2hâÿXŠmVg‡Rie‚d¶…DQ™d_±9òP¸2z—€?k/‰Þ.ñÌ_‰ÿf/‹Ó¥ó·ê÷ú÷…浇dné¹-µy&>c*ƸCƒ -µAaíðøwO¶×îu[{8õKÈ"µžñaQq<14o ™¦˜ª“…29Üsr—ÙK¯ë·õÐ'%)JIY;|¬¬þ÷ý^íümû(~Üÿ>,~Ô_ü5ñà?Ä­#CÑ5KH¬ÚïUðËGá•:%½×Ùî ¶¤ÒL÷±dhüõ_´Æ£ Êž•àÚß⇊n54ñì½ñkÉc¦Ü^Û½î¿áiF¡‰cgfúÁ»»h!XÍÔÅUL²{•D]Ç' £°«•WÒ ´bŸ›I&þo]~wwn-¬¼äߢné|¿á¬¬—ÄðOÛûã/ÇØÿPñoį?|C¯éú¦§ £Zêž·þßTÖîíE½ºÿhÆ‘½¤¢ÈÓƒ˜ÆÒ– þ³kû]üQºøw¬ê÷?²÷Å»-SN¸·‚ÛG—_ð«]j1Ȳ™'‰ÓXhU!1ÆI"1ó“b¸³Ýô/Øx_M[? XÙéÖhï"Ák ó»;°Ue™‰îX“É«l¡”†ƒÁ½*žüd–þÖß=5³*6‹»Ûúþ¿àh|]û~Þß~&þÁÿ|gã/Ùïâ—Œ"xßÁŸ~'øOÅ:n…­É—:¯…îdðÏÙì<èuYÔjrÅ4FcåF&”ý™ÃC†Mÿ^è°ðž…g¥øZÊÓLÓ4èÚÒÒÒ† X‘B¤qÆ **€P(×ô èwš_Š,­5-3Qí®í.¡Y º‰Ô«Ç$l º²’ AƒWVJr“еöòÛóëÓWkik¥(Âq”•Ò×õ÷ßSÀ£ý°>)'Ã-Y‡ö^ø·}ªjÍÆ“¿áU¹³#…’æGm`BRc,ŠªŽÎ /½P/ç¶÷íÕñ‹áG쵤x›áÿÀO‰z&»ªjºt7‹&­á‰¤Ð‘µ«Kcáµ'ŽG»†GXÚ4!™K´DO²ÕB(T0è*¦»áûi­gâk=FÍÝ$h.¡Y£fGŒUWU`{r**{îñÓúþŸü:O‘G›[~?Ößž§ƒkÿ¶Å='HÑ®tÏÙWâþ§>¥lóÝÚÁâ ¤šT‹<±ˆf2kJŽì‘¤ÀÄÒ&ÙÎlÛ§ãŸ|·ø{ðâY‡Å¾!²WŽ-[à ×>n4š>fÔ¾[ˆä†'iT¬$BÁg9 ÿeÕ=WÃöì¶o­ØÙÞ>p.íxVCm0VQ$eØá]Æáƒ†#¹©’mŧ´“ù'v¾ïø7WNÔ’æºÞ2_6šOäõü¬ìׇx÷ö´øá9ô´ðÏìÃñcÄë¦[ß\=Ž¿áxF<‰ºK9~Ñ«ÆZXÊÍx‰ûŽãšòÚóöýøËð‡ö»ø-áO‡~"ê‰u;ø¯Ò SÃCþ…Mk¡ojÓê!á{yÀgi ßgp(eöåS¿ðý†©©XÞjv6w7šc¼–sË ¼–ŒèQš&#(J3)+Œ†#¡«NÏúþ´ûÌÚ¿Ýý3ĵÿÚ»âf“ñtm/öeø«ªiFxb:ì÷†ÍQ“˓WYöǹƒ+'aÚOx›öûøÉ¦ÁOt†ÚÀ¿ˆ“x2o jWM êžnhµk+hõ¨Ýµ1mRdÌ,É9ó×ýJ}µTßÃökÑê¯cfÚ¤Víh—†7 2³D$Æà…‘®pJƒØS¦Ô*BM].k®÷‹Kîm?Ë[4¤¹¡(ßWkyY¦þõ§ü §âÖµOÄ›‹ËáÛÙ«â¤jÿÙçÅ ®xdéëoçyn0XÝy;?{°CæíãËÝòדü+ý»~0x»þ âx—à7ÄÝ7–þðüë Æ©á†MÜ_ëMªÌðêM,°L–ШŠ3,‹ö'>JO³jœ>ÓíµûVÞÆÎ=Rò­g¼XT\O M#GÈæDi¦*¤áLŽF7¨¾[_[~>¿ð-»ò¶§G«µ¼µOòþ­tü'µçÅ/xœØë²ÏÅÍÌEq'ö…߈<)$%£‰Þ4Û²òfWD‰NÜ‘K•PÌ<ÇöNý¼~1|Røãñ»Gñ÷À/‰ñiÞ×ü­6)µ_ ì ¾Ó¯L‘¡Ôó,×¼‰.e~ÝÉ,jޱ}¡TôÏéú-î¡s£ØÙÚ\êÓ‹«éa…c{ÉDi’V28Ž(“sdíW¢€=Öï­Ó_;­¯Êé¾eÛ¯ô½?3Ã|û[|OñÍpZÚ°ÃáDP`(iÜI5cæÿ‰¶oÅ] ölñGŠlf¿ŠzV½¦¬ñ[é³ë~’âŤ²ÿh]Y¡0ÆèˆÉ¼ÊK ±²äŽoöJý¹¾/üDýƒþxçÅ¿³çÄ¿x¯YÒ4–ºŠÏWðͼšÐ›OIåÕa©Åvï/'ò¦UýÊ€výyukõ´ÞÆ“C2”’7PÊêF ðAb¢Òt›MJ¶°Ð­­ì¬l¢H-íàŒG  ¨ˆ P€*âìª'×–Þ\¼×ÿÀ®¯éåXjüž\×ó½­÷Yÿ\×ø“þ ÿ øÕðoö ñ§¾~Ï¿<âk+ÃÝþ­á{¤ð÷”-ü«Ë„MNe–) Òª¬I3ƒ—ABþɬ~Öÿôßh:¦Ÿû/üYÔµUîVóHƒ_ð²Üèâ&ALòk ‰ƒ3/•$„;Â÷=Ãö*Ñ®tïXÙêZ}â絺…f†u=UÑVÄUÊm¦¶ÐøÃöàý»þ0ü$ø á sáÿÀO‰Ú>©­ø‹ÃÐjµ_ LÚRÏâ+[94ÙƒjN-å»ÒHw¤lžXYÅéÞ(ý®¾(èZF…q£þË5™õ[#sykmâ ¤š<¢i#ó™u•Wr‘¤»¢2&Ù”nÞWÝuÏéþ'²KoØÙê6ÑÏ ÒÅs Ì‹,2,±HÒDGVꬪÃW(¿ºÕ¾Ó~ŠËOOê÷nöÚíÓúÖší±ñ§íûtüaøSâÏ‚–ÿ~üK0ø·Ä6QêñÅ«xašçÍÓ¯æ“GÌÚ—ËqÄí*•„ˆX,ç!_Ñ|]û`üTðö¡o…û*|_×bšÊÚåçµñ„ãHe–’Kvk(Åávh™€(Z6(Î…Y½ëUðý†»-›ëv6w§\ »FžÛL”I`v8Wq¸`áˆîjåg⤟Y7ò²VûÓÿ‡»nrRq²Ú)|ù›¿­š_ðRø×ö†ýº>0ü7ý¸ü àïüø—®øfûI×'–;-[þ$xWN1Ïn×:’I[›‰•ÖC c*íY@Êz¿Œ?j_‰ø«. þÍ¿uí;¸í×Ä–šç†£°–6Ûºqú²\„MÍa v)ã>Ïuáû ífÓQ½±³›P°I#µºxU¦¶Y6ù‹‘” ±7Fv®z ¹N Å«ëúÿ^VÚ’²Ðø—Ä߷߯M3þ {¤|6ÓþüD›Á“xSRºhWTðÐûsE«Y[G­Fí¨ù‹jË&afIÏž¿èä‚SÙü1ûS|H×>+G k³gÅD{É-›Ä—:熞Á"RÛn QjÏrQö‚C¼nQÎ=ü?a&½ªö6mªEnÖ‰xaSp³+4BLnYŠç¨=…\§)Â/uÍwÞòm}É¥ÿÉLµ”šÙÚÞVŠOïzÿÁ»~Í?·çÆOŠ_ðP‰>ñ÷À¯ˆº'…´+ÃóAÞ©á§o 5ÄzƒKqtöú‹¼Ép`…QbiÙ<¦Ü±gæõ¿~×?<[âgâÙsâ߆-E­Ìâúû_ð¬Ð™#䎶úÄ’o•ÑaS·hi»"u÷K_ØXë7z•œ:† ‘ÇutªÍr±îòÖGs…ÞûA'›M\¦Ýútý7ý;‚Ñßúþ™ñWì¹û||eø‘ñ›ã†—ã_Ùóâ“ØøW_ò´Ëi5o )Ñø{N»M2FS̳\O4’¤¹’5ûljòÆ–/UðŸísñCÄf»>·û.|[Ñ&Ò¬>×gou¯øVGÖ&ó£O²ÀaÖRM’<»¥1Ƕ÷V÷M3ú~‹{¨\èö6v—:´âêúXaXÞòQD$•€ÌŽ#Š$ÜÙ;cUè  ”ÛM%o²—ÎÖ¿¯ù+ß[»«ßÏú_Ö¾gÅÿ±íãñ‹â×Ájß>|OÕõľ#·ÓÙu_ ÂÚ‚Ûø†æÒ-. šš*Íin<·–]‘Éö9 Ë+:}KCý­~'ê¾ ×u=Kö_ø³¦êSÛ-ž“>¿áfºÖ®Ë#@ñë B«7$d‡7@÷-ú†,ÞßÃV6z}¼³Ítñ[B°£Í4,²Pw‘ÝÙº³31É$ÕÊ™ûÉ[M?¯ëõÔm§)4·müžËåýid¾,ý‰?o_Œßÿb? x¿Ç_³ßÅx’æÂŤžÛWðµ¿ü$>rLe¼·S©Ä‘ÅŠ0Ë"ÂçÏM±°SsöŸý·>.ø'ö"øãO ~Ï_¼5â+LÕ¬Zφ&›HX´÷š=V]ºœÉn’ŒÔÉ)1ŸÜ°#wÕš‡ì<+£[éÞ²´Ótû4Ákk à ?…@ =€§êÚM®¿¥\Øë¶Ö÷¶7±4óÆ$ŠxØdt`C)‚Á•XJtå»6·íúþ7ìÓ±µ*°…hÔq¼S½»®Ý¿Nê×>vð_íƒñKPýŸt]~ÍŸuzòXí¦Ò#Öü.—’EöhäþÐÞue·»» A ”2œÆ«‚|×þ û~|eø#ûx§Ç? þüFð¿ŠbÓ/eóï5O \ 4OÅqvƒQ•&IDŽU`[†YÞ«•ÏÚö¶±XÛG ”qà *8ÑBª(ÀqН¯ø~ÃÅZ5Îâ‹=KO¼Cö·P¬ÐΧªº0*ÃØŠèœ“›’Z7·õý|¬rR‹„#jÖþ×ÞsŸ~"k¿~[êÿ¼ â‡:¤²È¢ëWvWq*œ,†K ›ˆqÈB@ꮾŠ*[¹QM+7p¢Š) (¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢Š(¢ŠÿÙpcs-0.6/docs/Makefile0000664000175000017500000000057411255512624014363 0ustar andreasandreas# # File: $Id: Makefile,v 1.1 2006/06/15 07:52:02 gnn Exp $ # # Author: George V. Neville-Neil # # Documentation Makefile for PCS. You can build various versions of # the docs from here. .SUFFIXES: .tex .pdf SRCS= pcs.tex design.tex all: ${SRCS:S/.tex/.pdf/} man latex .tex.pdf: pdflatex ${.IMPSRC} man:: doxygen clean:: rm -rf *.pdf *.html *.out *.log Web/html man latexpcs-0.6/docs/pcs.tex0000664000175000017500000010260111255512624014224 0ustar andreasandreas\documentclass[11pt]{article} \usepackage{codespelunking} \usepackage{fancyvrb} \usepackage{listings} \usepackage[pdftex]{hyperref} \title{Packet Construction Set} \author{George V. Neville-Neil} \begin{document} \maketitle \tableofcontents \begin{abstract} We had Ethernet headers, IP packets, TCP segments, a gaggle of HTTP requests and responses, also UDP, NTP, and DHCP. Not that we needed all that just to communicate but once you get locked into a serious packet collection the tendency is to push it as far as you can. - Deepest apologies to Hunter S. Thompson \end{abstract} % All code in this file is in Python, set the listings package correctly \lstset{language=Python, escapeinside={(*@}{@*)}, numbers=left} \section{Introduction} PCS is a set of Python modules and objects that make building network protocol testing tools easier for the protocol developer. The core of the system is the pcs module itself which provides the necessary functionality to create classes that implement packets. Installing PCS is covered in the text file, \file{INSTALLATION}, which came with this package. The code is under a BSD License and can be found in the file \file{COPYRIGHT} in the root of this package. In the following document we set \class{classes} \function{functions} and \method{methods} apart by setting them in different type. Methods and functions are also followed by parentheses, ``()'', which classes are not. \section{A Quick Tour} For the impatient programmer this section is a 5 minute intro to using PCS. Even faster than this tour would be to read some of the test code in the \file{tests} sub-directory or the scripts in the \file{scripts} sub directory. PCS is a set of functions to encode and decode network packets from various formats as well as a set of \emph{classes} for the most commonly use network protocols. Each object derived from a packet has fields automatically built into it that represent the relevant sections of the packet. Let's grab a familiar packet to work with, the IPv4 packet. IPv4 packets show a few interesting features of PCS. Figure \ref{fig:rfc791-ipheader} shows the definition of an IPv4 packet header from \cite{rfc791} which specifies the IPv4 protocol. \begin{figure} \label{fig:rfc791-ipheader} \centering \begin{Verbatim} 0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |Version| IHL |Type of Service| Total Length | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Identification |Flags| Fragment Offset | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Time to Live | Protocol | Header Checksum | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Source Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Destination Address | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Options | Padding | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \end{Verbatim} \caption{IPv4 Header Format} \end{figure} In PCS every packet class contains fields which represent the fields of the packet exactly, including their bit widths. Figure\ref{fig:ipv4-quick-and-dirty} shows a command line interaction with an IPv4 packet. \begin{figure} \centering \begin{lstlisting} >>> from pcs.packets.ipv4 import * >>> ip = ipv4() >>> print ip version 4 hlen 0 tos 0 length 0 id 0 flags 0 offset 0 ttl 64 protocol 0 checksum 0 src 0.0.0.0 dst 0.0.0.0 >>> ip.hlen=5<<2 >>> print ip version 4 hlen 20 tos 0 length 0 id 0 flags 0 offset 0 ttl 64 protocol 0 checksum 0 src 0.0.0.0 dst 0.0.0.0 \end{lstlisting} \caption{Quick and Dirty IPv4 Example} \label{fig:ipv4-quick-and-dirty} \end{figure} Each packet has a built in field called \field{bytes} which always contains the wire representation of the packet. \begin{figure} \centering \begin{Verbatim} >>> from pcs.packets.ipv4 import * >>> ip = ipv4() >>> ip.bytes '@\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' >>> ip.hlen = 5 << 2 >>> ip.bytes 'D\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' \end{Verbatim} \caption{The \field{bytes} Field of the Packet} \label{fig:bytes-field} \end{figure} In Figure\ref{fig:bytes-field} the \field{bytes} field has been changed in its first position by setting the \field{hlen} or header length field to 20, $5 \ll 2$. Such programmatic access is available to all fields of the packet. The IPv4 header has fields that can be problematic to work with in any language including ones that are \begin{list}{fig:ipheadfeatures}{} \item less than one byte (octect) in length (Version, IHL, Flags) \item not an even number of bits (Flags) \item not aligned on a byte boundary (Fragment Offset) \end{list} Using just these features it is possible to write complex programs in Python that directly manipulate packets. For now you should know enough to safely ignore this documentation until you to explore further. \section{Working with Packets} In PCS every packet is a class and the layout of the packet is defined by a Layout class which contains a set of Fields. Fields can be from 1 to many bits, so it is possible to build packets with arbitrary width bit fields. Fields know about the widths and will throw exceptions when they are overloaded. Every Packet object, that is an object instantiated from a specific PCS packet class, has a field named bytes which shows the representation of the data in the packet at that point in time. It is the bytes field that is used when transmitting the packet on the wire. The whole point of writing PCS was to make it easier to experiment with various packet types. In PCS there are packet classes and packet objects. Packet classes define the named fields of the packet and these named fields are properties of the object. A practical example may help. Given an IPv6 packet class it is possible to create the object, set various fields, as well as transmit and receive the object. A good example is the IPv6 class: \begin{figure} \centering \begin{lstlisting} ip = ipv6() assert (ip != None) ip.traffic_class = 1 ip.flow = 0 ip.length = 64 ip.next_header = 6 ip.hop = 64 ip.src = inet_pton(AF_INET6, "::1") ip.dst = inet_pton(AF_INET6, "::1") \end{lstlisting} \caption{IPv6 Class} \label{fig:ipv6-class} \end{figure} The code in Figure \ref{fig:ipv6-class} gets a new IPv6 object from the ipv6() class, which was imported earlier, and sets various fields in the packet. Showing the bytes field, Figure \ref{fig:bytes-ipv6-packet} gives us an idea of how well this is working. \begin{figure} \centering \begin{Verbatim} >>> ip.bytes '`\x10\x00\x00\x00@\x06@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' \end{Verbatim} \caption{Bytes of the IPv6 Packet} \label{fig:bytes-ipv6-packet} \end{figure} Note that various bits are set throughout the bytes. The data in the packet can be pretty printed using the \function{print} function as seen in Figure \ref{fig:printing-a-packet} or it can be dumped as a string directly as seen in Figure\ref{fig:repr-method}. \begin{figure} \centering \begin{lstlisting} >>> print ip version 6 traffic_class 1 flow 0 length 64 next_header 6 hop 64 src ::1 dst ::1 \end{lstlisting} \caption{Printing a Packet} \label{fig:printing-a-packet} \end{figure} \begin{figure}[h] \centering \begin{Verbatim} >>> ip \end{Verbatim} \caption{Using the \method{\_\_repr\_\_} method} \label{fig:repr-method} \end{figure} \section{Creating Packet Classes} For a packet to be a part of PCS it must sub-classed from the \class{Packet} class as seen in Figure \ref{fig:ipv6-class-definition}. Thoughout this section we will use the example of a network layer packet, IPv6, and a packet about the transport layer, DNS. Using both low and high level packets should give the reader a good feel for how to add most of the packets they would be expected to work with. \begin{figure} \centering \begin{lstlisting} class ipv6(pcs.Packet): """A class that contains the IPv6 header. All other data is chained on the end.""" _layout = pcs.Layout() _map = None def __init__(self, bytes = None): """IPv6 Packet from RFC 2460""" version = pcs.Field("version", 4, default = 6) (*@\label{list:field_begin}@*) traffic = pcs.Field("traffic_class", 8) flow = pcs.Field("flow", 20) length = pcs.Field("length", 16) next_header = pcs.Field("next_header", 8, discriminator=True) hop = pcs.Field("hop", 8) src = pcs.StringField("src", 16 * 8) dst = pcs.StringField("dst", 16 * 8)(*@\label{list:field_end}@*) pcs.Packet.__init__(self, [version, traffic, flow, length, next_header, hop, src, dst], bytes) self.description = "IPv6" self._map = ipv6_map.map if (bytes != None): (*@\label{list:next_begin}@*) ## 40 bytes is the standard size of an IPv6 header offset = 40 self.data = self.next(bytes[offset:len(bytes)]) else: self.data = None(*@\label{list:next_end}@*) \end{lstlisting} \caption{IPv6 Packet Class} \label{fig:ipv6-class-definition} \end{figure} The code in Figure \ref{fig:ipv6-class-definiition} defines a new class, one that will describe an IPv6 packet, sub-classed from the \class{Packet} base class. There are a small number of reserved field names that you \emph{must not} use when defining your packets. For reference all of the reserved field names are given in Table~\ref{fig:reserved_fields_and_methods} and most of them will also be discussed in this section. Resereved names that are part of a class, as opposed to an object, are preceeded by an underscore, \_, to further set them apart. Do not use underscores to start your fieldnames. \emph{You have been warned!} \begin{figure} \centering \begin{tabular}{|l|l|} \hline Field Name & Use \\ \hline \texttt{\_layout} & Used to store the layout of the packet\\ \hline \texttt{\_map} & Used to demultiplex higher layer packets\\ \hline \texttt{next} & A method used to unencapsulate higher layer packets\\ \hline \texttt{bytes} & Storage for the raw bytes of the packet\\ \hline \texttt{data} & Pointer to the next higher layer packet\\ \hline \texttt{description} & Textual description of the packet\\ \hline \end{tabular} \caption{Reserved Fields and Methods in PCS} \label{fig:reserved_fields_and_methods} \end{figure} Each packet class in PCS is defined in a similar way. After sub-classing from the \class{Packet} class, there should be a Python style text string describing the class. The fields are defined next,as shown on lines \ref{list:field_begin} through \ref{list:field_end}, in the order in which they are stored in the packet. Various types of fields are supported by PCS and they are all covered in Section~\ref{sec:}. After all of the fields have been listed, the \class{Packet} class's \method{init} method is called with three arguments. The \class{self} object, an array of the fields, in the order in which they will appear in a packet, and the \field{bytes} variable that was passed to the packet object's \method{init} method. Once the packet is initalized we set its description, on line 20. Any packet that may contain data at a higher layer, such as a network packet will then use its \method{next} method to unencapsulate any higher layer packets. On lines \ref{list:next_begin} through \ref{list:next_end} the \method{init} method attempts to unencapsulate any data after the header itself. Every packet object either has a valid \field{data} or it is set to \constant{None}. Higher level programs using PCS will check for \field{data} being set to \variable{None} in order to know when they have reached the end of a packet so it must be set correctly by each packet class. The \method{next} method used here is from the \class{Packet} base class but it can also be overridden by a programmer, and this is done in the \class{TCP} class which can be found in \file{pcs/packets/tcp.py}. \subsection{Working with Different Types of Fields} \label{sec:working_with_different_types_of_fields} Part of packet initialization is to set up the fields that the packet will contain. Fields in PCS are objects in themselves and they are initialized in different ways, depending on their type. A brief list of the currently supported fields is given in Table~\ref{fig:fields_supported_by_pcs}. \begin{figure} \centering \begin{tabular}{|l|l|l|} \hline Name & Use & Initialiazation Arguments\\ \hline Field & Abitrary Bit Field & Name, Width in Bits, Default Value\\ \hline StringField & String of Bytes & Name, Width In Bits, Default Value\\ \hline LengthValueField & A set of Values with Associated Lengths & Name, Width in Bytes, Default Value\\ \hline \end{tabular} \caption{Fields Supported by PCS} \label{fig:fields_supported_by_pcs} \end{figure} Each field has several possible arguments, but the two that are required are a name, which is the string field specified as the first argument and a width, which is the second argument. Note that some field widths are specified in \emph{bits} and some in \emph{bytes} or The fields are set by passing them as an array to the PCS base class initialization method. It would have been convenient if all network protocol packets were simply lists of fixed length fields, but that is not the case. PCS defines two extra field classes, the \class{StringField} and the \class{LengthValueField}. The \class{StringField} is simply a name and a width in bits of the string. The data is interpreted as a list of bytes, but without an encoded field size. Like a \class{Field} the \class{StringField} has a constant size. Numerous upper layer protocols, i.e. those above UDP and TCP, use length-value fields to encode their data, usually strings. In a length-value field the number of bytes being communicated is given as the first byte, word, or longword and then the data comes directly after the size. For example, DNS~\cite{rfc1035} encodes the domain names to be looked up as a series of length-value fields such that the domain name pcs.sourceforge.net gets encoded as 3pcs11sourceforge3net when it is transmitted in the packet. The \class{LengthValueField} class is used to encode length-value fields. A \class{LenghtValueField} has three attributes, its name, the width in bits of the length part, and a possible default value. Currently only 8, 16, and 32 bit fields are supported for the length. The length part need never been set by the programmer, it is automatically set when a string is assigned to the field as shown in~\ref{fig:using-a-length-value-field}. \begin{figure} \centering \begin{lstlisting} class dnslabel(pcs.Packet): """A DNS Label.""" layout = pcs.Layout() def __init__(self, bytes = None): name = pcs.LengthValueField("name", 8) pcs.Packet.__init__(self, [name], bytes = bytes) self.description = "DNS Label" ... lab1 = dnslabel() lab1.name = "pcs" lab2 = dnslabel() lab2.name = "sourceforge" lab3 = dnslabel() lab3.name = "net" lab4 = dnslabel() lab4.name = "" \end{lstlisting} \caption{Using a \class{LengthValueField}} \label{fig:using-a-length-value-field} \end{figure} Figure~\ref{fig:using-a-length-value-field} shows both the definition and use of a \class{LengthValueField}. The definition follows the same system as all the other fields, with the name and the size given in the initialization. The \class{dnslabel} class has only one field, that is the name, and it's length is given by an 8 bit field, meaning the string sent can have a maximum length of 255 bytes. When using the class, as mentioned, the size is not explicitly set. One last thing to note is that in order to have a 0 byte terminator the programmer assigns the empty string to a label. Using the empty string means that the length-value field in the packet has a 0 for the length which acts as a terminator for the list. For a complete example please review \file{dns\_query.py} in the \file{scripts} directory. \subsection{Built in Bounds Checking} \label{sec:built-in-bounds-checking} One of the nicer features of PCS is built in bounds checking. Once the programmer has specified the size of the field, the system checks on any attempt to set that field to make sure that the value is within the proper bounds. For example, in Figure \ref{fig:bounds-checking-1} an attempt to set the value of the IP packet's header length field to $16$ fails because the header length field is only 4 bits wide and so must contain a value between zero and fifteen. \begin{figure} \centering \begin{lstlisting} >>> from pcs.packets.ipv4 import * >>> ip = ipv4() >>> ip.hlen = 16 Traceback (most recent call last): [...] pcs.FieldBoundsError: 'Value must be between 0 and 15' >>> ip.hlen = -1 Traceback (most recent call last): [...] pcs.FieldBoundsError: 'Value must be between 0 and 15' >>> \end{lstlisting} \caption{Bounds Checking} \label{fig:bounds-checking-1} \end{figure} \program{PCS} does all the work for the programmer once they have set the layout of their packet. \subsection{Decapsulating Packets} \label{sec:decapsulating_packets} One of the key concepts in networking is that of encapsulation, for example an IP packet can be encapsulated in an Ethernet frame. In order to provide a simple way for programmers to specifying the mapping between different layers of protocols \program{PCS} provides a \method{next} method as part of the \class{Packet} base class. There are a few pre-requisites that the programmer must fulfill in order for the \method{next} method to do its job. The first is that at least one \class{Field} must be marked as a \emph{discriminator}. The descriminator field is the one that the \method{next} method will use to decapsulate the next higher layer packet. The other pre-requisite is that the programmer define a mapping of the discriminator values to other packets. An example seems the best way to make sense of all this. \begin{figure} \begin{lstlisting} import pcs import ethernet_map class ethernet(pcs.Packet): _layout = pcs.Layout() _map = None(*@\label{list:map_class_variable}@*) def __init__(self, bytes = None): """initialize an ethernet packet""" src = pcs.StringField("src", 48) dst = pcs.StringField("dst", 48) type = pcs.Field("type", 16, discriminator=True) etherlen = 14 pcs.Packet.__init__(self, [dst, src, type], bytes = bytes) self.description = "Ethernet" self._map = ethernet_map.map(*@\label{list:setup_the_map}@*) if (bytes != None): self.data = self.next(bytes[etherlen:len(bytes)]) else: self.data = None ... import ipv4, ipv6, arp (*@\label{list:importing_higher_layer_packets}@*) ETHERTYPE_IP = 0x0800 # IP protocol ETHERTYPE_ARP = 0x0806 # Addr. resolution protocol ETHERTYPE_IPV6 = 0x86dd # IPv6 map = {ETHERTYPE_IP: ipv4.ipv4,(*@\label{list:start_the_mapping}@*) ETHERTYPE_ARP: arp.arp, ETHERTYPE_IPV6: ipv6.ipv6}(*@\label{list:end_the_mapping}@*) \end{lstlisting} \caption{The Ethernet Packet and Mapping Classes} \label{fig:ethernet_packet_and_mapping_classes} \end{figure} Figure \ref{fig:ethernet_packet_and_mapping_classes} shows an abbreviated and combined listing of the \class{Ethernet} class and its associated mapping class. The full implementation can be found in the source tree in the files \filepath{pcs/packets/ethernet.py} and \filepath{pcs/packets/ethernet_map.py} respectively. On line \ref{list:map_class_variable} a class variable, one that will be shared across all instances of this object, is created and set to the map that is defined in the \module{ethernet_map} module. The actual mapping of discriminators to higher layer packets is done in the mapping module. Line \ref{list:importing_higher_layer_packets} shows the mapping module importing the higher layer objects, in this case the \class{ipv4}, \class{ipv6}, and \class{arp} packets which can be encapsulated in an Ethernet frame. The map is really a \program{Python} dictionary where the key is the value that the \method{next} method expects to find in the field marked as a \emph{discriminator} in the \class{ethernet} packet class. The values in the dictionary are packet class constructors which will be called from PCS's \class{Packet} base class. If the preceeding discussion seems complicated it can be summed up in the following way. A packet class creator marks a single \class{Field} as a \emph{discriminator} and then creates a mapping module which contains a dictionary that maps a value that can appear as a discriminator to a consctructor for a higher layer packet class. In the case of Ethernet the discriminator is the \field{type} field which contains the protocol type. An Ethernet frame which contains an IPv4 packet will have a \field{type} field containing the value $2048$ in decimal, $0x800$ hexadecimal. The \class{Packet} base class in this case will handle decapsulation of the higher layer packet. Mapping classes exist now for most packets, although some packets, such as TCP and UDP, require special handling. Refer to the \method{next} method implementations in \filepath{pcs/packets/tcp.py} and \filepath{pcs/packets/udp.py} for more information. \section{Retrieving Packets} \label{sec:retrieving-packets} One of the uses of \program{PCS} is to analyze packets that have previously stored, for example by a program such as \program{tcpdump(1)}. \program{PCS} supports reading and writing \program{tcpdump(1)} files though the \href{http://monkey.org/~dugsong/pypcap/}{pcap} library written by Doug Song. The python API exactly mirrors the C API in that packets are processed via a callback to a \function{dispatch} routine, usually in a loop. Complete documentation on the \program{pcap} library can be found with its source code or on its web page. This document only explains \program{pcap} as it relates to how we use it in \program{PCS}. When presented with a possibly unknown data file how can you start? If you don't know the bottom layer protocol stored in the file, such as \emph{Ethernet}, \emph{FDDI}, or raw \emph{IP} packets such as might be capture on a loopback interface, it's going to be very hard to get your program to read the packets correctly. The \program{pcap} library handles this neatly for us. When opening a saved file it is possible to ask the file what kind of data it contains, through the \method{datalink} method. \begin{figure} \centering \begin{lstlisting} >>> import pcap >>> efile = pcap.pcap("etherping.out") >>> efile.datalink() 1 >>> efile.datalink() == pcap.DLT_EN10MB True >>> lfile = pcap.pcap("loopping.out") >>> lfile.datalink() 0 >>> lfile.datalink() == pcap.DLT_NULL True >>> lfile.datalink() == pcap.DLT_EN10MB False >>> \end{lstlisting} \caption{Determining the Bottom Layer} \label{fig:determining-the-bottom-layer} \end{figure} In Figure\ref{fig:determining-the-bottom-layer} we see two different save files being opened. The first, \file{etherping.out} is a tcpdump file that contains data collected on an Ethernet interface, type \constant{DLT\_EN10} and the second, \file{loopping.out} was collected from the \emph{loopback} interface and so contains no Layer 2 packet information. Not only do we need to know the type of the lowest layer packets but we also need to know the next layer's offset so that we can find the end of the datalink packet and the beginning of the network packet. The \field{dloff} field of the \class{pcap} class gives the data link offset. Figure\ref{fig:finding-the-datalink-offset} continues the example shown in Figure\ref{fig:determining-the-bottom-layer} and shows that the Ethernet file has a datalink offset of 14 bytes, and the loopback file 4. \begin{figure} \centering \begin{lstlisting} >>> efile.dloff 14 >>> lfile.dloff 4 >>> \end{lstlisting} \caption{Finding the Datalink Offset} \label{fig:finding-the-datalink-offset} \end{figure} It is in the loopback case that the number is most important. Most network programmers remember that Ethernet headers are 14 bytes in length, but the 4 byte offset for loopback may seem confusing, and if forgotten any programs run on data collected on a loopback interface will appear as garbage. With all this background we can now read a packet and examine it. Figure \ref{fig:reading-in-a-packet} shows what happens when we create a packet from a data file. \begin{figure} \centering \begin{lstlisting} >>> ip = ipv4(packet[efile.dloff:len(packet)]) >>> print ip version 4 hlen 5 tos 0 length 84 id 34963 flags 0 offset 0 ttl 64 protocol 1 checksum 58688 src 192.168.101.166 dst 169.229.60.161 \end{lstlisting} \caption{Reading in a Packet} \label{fig:reading-in-a-packet} \end{figure} In this example we pre-suppose that the packet is an IPv4 packet but that is not actually necessary. We can start from the lowest layer, which in this case is Ethernet, because the capture file knows the link layer of the data. Packets are fully decoded as much as possible when they are read. \begin{figure} \centering \begin{lstlisting} >>> from pcs.packets.ethernet import ethernet >>> ethernet = ethernet(packet[0:len(packet)]) >>> ethernet.data >>> ip = ethernet.data >>> print ethernet src: 0:10:db:3a:3a:77 dst: 0:d:93:44:fa:62 type: 0x800 >>> print ip version 4 hlen 5 tos 0 length 84 id 34963 flags 0 offset 0 ttl 64 protocol 1 checksum 58688 src 192.168.101.166 dst 169.229.60.161 \end{lstlisting} \caption{Packet Decapsulation on Read} \label{fig:packet-decapsulation-on-read} \end{figure} PCS is able to do this via a special method, called \method{next} and a field called \field{data}. Every PCS class has a \method{next} method which attempts to figure out the next higher layer protocol if there is any data in a packet beyond the header. If the packet's data can be understand and a higher layer packet class is found the \method{next} creates a packet object of the appropriate type and sets the \field{data} field to point to the packet. This process is recursive, going up the protocol layers until all remaining packet data or higher layers are exhausted. In Figure\ref{fig:packet-decapsulation-on-read} we see an example of an Ethernet packet which contains an IPv4 packet which contains an ICMPv4 packet all connected via their respective \field{data} fields. \section{Storing Packets} This section intentionally left blank. Need to update \program{pcap} module to include support for true dump files. \section{Sending Packets} \label{sec:sending-packets} In \program{PCS} packets are received and transmitted (see \ref{sec:sending-packets} using \class{Connectors}. A \class{Connector} is an abstraction that can contain a traditional network \emph{socket}, or a file descriptor which points to a protocol filter such as \emph{BPF}. For completely arbitrary reasons we will discuss packet transmission first. In order to send a packet we must first have a connector of some type on which to send it. A trivial example is the \file{http\_get.py} script which uses a \class{TCP4Connector} to contact a web server, execute a simple \em{GET} command, and print the results. \begin{figure} \centering \begin{lstlisting} import pcs from socket import * def main(): conn = pcs.TCP4Connector("127.0.0.1", 80) conn.write("GET / \n") result = conn.read(1024) print result main() \end{lstlisting} \caption{HTTP Get Script} \label{fig:http-get-script} \end{figure} Although everything that is done in the \program{http\_get} script could be done far better with \program{Python's} native HTTP classes the script does show how easy it is to set up a connector. For the purposes of protocol development and testing it is more interesting to look at the \class{PcapConnector} class, which is used to read and write raw packets to the network. Figure \ref{fig:transmitting-a-raw-ping-packet} shows a section of the \program{icmpv4test} test script which transmits an ICMPv4 echo, aka ping, packet. \footnote{Note that on most operating system you need root privileges in use the \class{PcapConnector} class.} \begin{figure} \centering \begin{lstlisting} def test_icmpv4_ping(self): ip = ipv4() ip.version = 4 ip.hlen = 5 ip.tos = 0 ip.length = 84 ip.id = 1 ip.flags = 0 ip.offset = 0 ip.ttl = 33 ip.protocol = IPPROTO_ICMP ip.src = 2130706433 ip.dst = 2130706433 icmp = icmpv4() icmp.type = 8 icmp.code = 0 icmp.cksum = 0 echo = icmpv4echo() echo.id = 32767 echo.seq = 1 lo = localhost() lo.type = 2 packet = Chain([lo, ip, icmp, echo]) icmp_packet = Chain([icmp, echo]) icmp.checksum = icmp_packet.calc_checksum() packet.encode() input = PcapConnector("lo0") input.setfilter("icmp") output = PcapConnector("lo0") out = output.write(packet.bytes, 88) \end{lstlisting} \caption{Transmitting a Raw Ping Packet} \label{fig:transmitting-a-raw-ping-packet} \end{figure} The \function{test\_icmpv4\_ping} function contains a good deal of code but we are only concerned with the last two lines at the moment. The next to the last line opens a raw pcap socket on the localhost, \em{lo0}, interface which allows us to write packets directly to that interface. The last line writes a packet to the interface. We will come back to this example again in section \ref{sec:chains}. \section{Receiving Packets} \label{sec:receiving-packets} In order to receive packets we again use the \class{Connector} classes. Figure \ref{fig:packet-snarfing-program} shows the simplest possible packet sniffer program that you may ever see. \begin{figure} \centering \begin{lstlisting} import pcs from pcs.packets.ethernet import ethernet def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--interface", dest="interface", default=None, help="Which interface to snarf from.") (options, args) = parser.parse_args() snarf = pcs.PcapConnector(options.interface) while 1: packet = ethernet(snarf.read()) print packet print packet.data main() \end{lstlisting} \caption{Packet Snarfing Program} \label{fig:packet-snarfing-program} \end{figure} The \program{snarf.py} reads from a selected network interface, which in this case must be an Ethernet interface, and prints out all the Ethernet packets and \emph{any upper level packets that PCS knows about.} It is this second point that should be emphasized. Any packet implemented in \program{PCS} which has an upper layer protocol can, and should, implement a \method{next} method which correctly fills in the packet's \field{data} field with the upper level protocol. In this case the upper layer protocols are likely to be either ARP, IPv4 or IPv6, but there are others that are possible. \section{Chains} \label{sec:chains} We first saw a the \class{Chain} class in Figure \ref{fig:transmitting-a-raw-ping-packet} and we'll continue to refer to that figure here. \class{Chains} are used to connect several packets together, which allows use to put any packet on top of any other. Want to transmit an Ethernet packet on top of ICMPv4? No problem, just put the Ethernet packet after the ICMPv4 packet in the chain. Apart from creating arbitrary layering, \class{Chains} allow you to put together better known set of packets. In order to create a valid ICMPv4 echo packet we need to have a IPv4 packet as well as the proper framing for the localhost interface. When using \program{pcap} directly even the localhost interface has some necessary framing to indicate what type of packet is being transmitted over it. The packet we're to transmit is set up as a \class{Chain} that contains four other packets: localhost, IPv4, ICMPv4, and Echo. Once the chain is created it need not be static, as in this example, as changes to any of the packets it contains will be reflected in the chain. In order to update the actual bytes the caller has to remember to invoke the \method{encode} method after any changes to the packets the chain contains. \footnote{This may be fixed in a future version to make \class{Chains} more automatic.} \class{Chains} can also calculate RFC 792 style checksums, such as those used for ICMPv4 messages. The checksum feature was used in Figure~\ref{fig:transmitting-a-raw-ping-packet}. Because it is common to have to calculate checksums over packets it made sense to put this functionality into the \class{Chain} class. \section{Displaying Packets} \label{sec:displaying-packets} \begin{Verbatim} To be done, to be done... \end{Verbatim} \end{document} \begin{thebibliography}{99} \bibitem{rfc791} Postel J.: RFC 791 Internet Protocol \bibitem{rfc1035} Mockapetris P..: RFC 1035 Domain Names - Implementation and Specification \end{thebibliography} pcs-0.6/docs/Doxyfile0000664000175000017500000014515711255512624014440 0ustar andreasandreas# Doxyfile 1.5.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = PCS # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = 0.4 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, # Italian, Japanese, Japanese-en (Japanese with English messages), Korean, # Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, # Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. OUTPUT_LANGUAGE = English # This tag can be used to specify the encoding used in the generated output. # The encoding is not always determined by the language that is chosen, # but also whether or not the output is meant for Windows or non-Windows users. # In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES # forces the Windows encoding (this is the default for the Windows binary), # whereas setting the tag to NO uses a Unix-style encoding (the default for # all platforms other than Windows). USE_WINDOWS_ENCODING = NO # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will # prepend the brief description of a member or function before the # detailed description. Note: if both HIDE_UNDOC_MEMBERS and # BRIEF_MEMBER_DESC are set to NO, the brief descriptions will be # completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description # abbreviator that is used to form the text in various listings. Each # string in this list, if found as the leading text of the brief # description, will be stripped from the text and the result after # processing the whole list, is used as the annotated text. Otherwise, # the brief description is used as-is. If left blank, the following # values are used ("$name" is automatically replaced with the name of # the entity): "The $name class" "The $name widget" "The $name file" # "is" "provides" "specifies" "contains" "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES # then Doxygen will generate a detailed section even if there is only # a brief description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like the Qt-style comments (thus requiring an # explicit @brief command for a brief description. JAVADOC_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of # Java sources only. Doxygen will then generate output that is more # tailored for Java. For instance, namespaces will be presented as # packages, qualified scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do # not want to include (a tag file for) the STL sources as input, then # you should set this tag to YES in order to let doxygen match # functions declarations and definitions whose arguments contain STL # classes (e.g. func(std::string); v.s. func(std::string) {}). This # also make the inheritance and collaboration diagrams that involve # STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple # directories then setting the SHOW_DIRECTORIES tag to YES will show # the directory hierarchy in the documentation. The default is NO. SHOW_DIRECTORIES = NO # The FILE_VERSION_FILTER tag can be used to specify a program or # script that doxygen should invoke to get the current version for # each file (typically from the version control system). Doxygen will # invoke the program by executing (via popen()) the command # , where is the value of the # FILE_VERSION_FILTER tag, and is the name of an input # file provided by doxygen. Whatever the program writes to standard # output is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories # that contain documented source files. You may enter file names like # "myfile.cpp" or directories like "/usr/src/myproject". Separate the # files or directories with spaces. INPUT = ../pcs # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files # will be generated. Documented entities will be cross-referenced with # these sources. Note: To get rid of all source code in the generated # output, make sure also VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES (the default) # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES (the default) # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = Web/html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compressed HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # If the GENERATE_TREEVIEW tag is set to YES, a side panel will be # generated containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = YES # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = NO # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a call dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable call graphs for selected # functions only using the \callgraph command. CALL_GRAPH = YES # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will # generate a caller dependency graph for every global function or class method. # Note that enabling this option will significantly increase the time of a run. # So in most cases it will be better to enable caller graphs for selected # functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_WIDTH = 1024 # The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height # (in pixels) of the graphs generated by dot. If a graph becomes larger than # this value, doxygen will try to truncate the graph, so that it fits within # the specified constraint. Beware that most browsers cannot cope with very # large images. MAX_DOT_GRAPH_HEIGHT = 1024 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that a graph may be further truncated if the graph's # image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH # and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), # the graph is not depth-constrained. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, which results in a white background. # Warning: Depending on the platform used, enabling this option may lead to # badly anti-aliased labels on the edges of a graph (i.e. they become hard to # read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO pcs-0.6/COPYRIGHT0000664000175000017500000000272211255512624013263 0ustar andreasandreasCopyright (c) 2006, Neville-Neil Consulting All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of Neville-Neil Consulting nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. pcs-0.6/CONTRIBUTORS0000664000175000017500000000053211255512624013645 0ustar andreasandreasAll contributors are listed in chronological order John-Mark Gurney (jmg at freebsd.org) Li-Wen Hsu (lwhsu at lwhsu.ckefgisc.org) Clément Lecigne (clemun at gmail.com) Kip Macy (kmacy at freebsd dot org) Tom McLaughlin (tmclaugh at sdf.lonestar.org) Chuck Tuffli (ctuffli at users.sourceforge.net) Bruce M Simpson (bms at freebsd.org) pcs-0.6/tests/0000775000175000017500000000000011323556365013135 5ustar andreasandreaspcs-0.6/tests/dhcpv4test.py0000664000175000017500000001477511255512624015607 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: This module performs a self test on a DHCPv4 packet. import unittest import sys from hexdumper import hexdumper if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import inet_atol from pcs import PcapConnector from pcs.packets.ethernet import ether_atob from pcs.packets.ethernet import ether_btoa from pcs.packets.ipv4 import * from pcs.packets.udp import * from pcs.packets import dhcpv4 from pcs.packets.dhcpv4 import * from pcs.packets import dhcpv4_options from pcs.packets.dhcpv4_options import * class bootpTestCase(unittest.TestCase): def test_dhcpv4_encode(self): p = dhcpv4() assert (p != None) p.op = pcs.packets.dhcpv4.BOOTREQUEST p.htype = pcs.packets.dhcpv4.HTYPE_ETHER p.hlen = 6 # sizeof(struct ether_addr) p.hops = 99 p.xid = 0xABADCAFE p.secs = 123 p.flags = pcs.packets.dhcpv4.BOOTP_BROADCAST p.ciaddr = inet_atol("1.2.3.4") p.yiaddr = inet_atol("5.6.7.8") p.siaddr = inet_atol("9.10.11.12") p.giaddr = inet_atol("13.14.15.16") p.chaddr = ether_atob("00:01:02:03:04:05") p.sname = "fubar" p.file = "barfu" # Append DHCP options, which MUST include the cookie. p.options.append(dhcpv4_options.cookie().field()) # Maximum DHCP message size. msz = dhcpv4_options.dhcp_max_message_size() msz.value = 1460 p.options.append(msz.field()) # DHCP message type. dhcp = dhcpv4_options.dhcp_message_type() dhcp.value = DHCPDISCOVER p.options.append(dhcp.field()) # DHCP vendor class. vc = dhcpv4_options.dhcp_class_identifier() vc.value = "FreeBSD:amd64:7-CURRENT" p.options.append(vc.field()) # BOOTP options end marker. end = dhcpv4_options.end() p.options.append(end.field()) # Pad BOOTP payload to 32-bit width. padlen = 4 - (len(p.bytes) % 4) pad = dhcpv4_options.pad(padlen) p.options.append(pad.field()) p.encode() #hd = hexdumper() #print p #print hd.dump2(p.bytes) gotttted = p.bytes expected = \ "\x01\x01\x06\x63\xAB\xAD\xCA\xFE" \ "\x00\x7B\x80\x00\x01\x02\x03\x04" \ "\x05\x06\x07\x08\x09\x0A\x0B\x0C" \ "\x0D\x0E\x0F\x10\x00\x01\x02\x03" \ "\x04\x05\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x66\x75\x62\x61" \ "\x72\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x62\x61\x72\x66" \ "\x75\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x63\x82\x53\x63" \ "\x39\x02\x05\xB4\x35\x01\x01\x3C" \ "\x17\x46\x72\x65\x65\x42\x53\x44" \ "\x3A\x61\x6D\x64\x36\x34\x3A\x37" \ "\x2D\x43\x55\x52\x52\x45\x4E\x54" \ "\xFF\x00\x00\x00" self.assertEqual(expected, gotttted, "test encoding") def test_dhcpv4_decode(self): """This test reads from a pre-stored pcap file.""" file = PcapConnector("dhcp_minimal.pcap") packet = file.readpkt() chain = packet.chain() #print chain ether = chain.packets[0] assert (ether != None) ip = chain.packets[1] assert (ip != None) udp = chain.packets[2] assert (udp != None) dhcp = chain.packets[3] assert (dhcp != None) self.assertEqual(dhcp.op, 1, "op not equal") self.assertEqual(dhcp.xid, 0xffff0001, "xid not equal") self.assertEqual(dhcp.secs, 42848, "secs not equal") self.assertEqual(dhcp.flags, 0x8000, "flags not equal") mac = ether_atob("52:54:00:12:34:56") #print ether_btoa(dhcp.chaddr) self.assertEqual(dhcp.chaddr[:dhcp.hlen], mac, "mac not equal") self.assertEqual(len(dhcp.options), 6, "wrong option field count %d should be %d" % (len(dhcp.options), 6)) # Not a tlv field self.assertEqual(dhcp.options[0], pcs.packets.dhcpv4_options.DHCP_OPTIONS_COOKIE, "invalid cookie value") # TLV fields self.assertEqual(dhcp.options[1].value, 1460, "invalid maximum message size value") self.assertEqual(dhcp.options[2].value, "FreeBSD:i386:6.3-RELEASE", \ "invalid vendor class") self.assertEqual(dhcp.options[3].value, pcs.packets.dhcpv4_options.DHCPDISCOVER, "invalud dhcp message type") # Not a tlv field self.assertEqual(dhcp.options[4], pcs.packets.dhcpv4_options.DHO_END, "invalid end value") if __name__ == '__main__': unittest.main() pcs-0.6/tests/boundstest.py0000664000175000017500000001225511255512624015700 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id:$ # # Author: George V. Neville-Neil # # Description: A simple test of all the bound checking code in PCS import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs from pcs.packets.ipv4 import * from pcs.packets.ethernet import * from pcs.packets.dns import * class boundaryPacket(pcs.Packet): """Define a packet full of bit fields for use in testing. """ _layout = pcs.Layout() def __init__(self, bytes = None): f1 = pcs.Field("f1", 1) f2 = pcs.Field("f2", 2) f3 = pcs.Field("f3", 3) f4 = pcs.Field("f4", 4) f5 = pcs.Field("f5", 5) f6 = pcs.Field("f6", 6) f7 = pcs.Field("f7", 7) f8 = pcs.Field("f8", 8) f9 = pcs.Field("f9", 9) f10 = pcs.Field("f10", 10) f11 = pcs.Field("f11", 11) f12 = pcs.Field("f12", 12) f13 = pcs.Field("f13", 13) f14 = pcs.Field("f14", 14) f15 = pcs.Field("f15", 15) f16 = pcs.Field("f16", 16) f17 = pcs.Field("f17", 17) f18 = pcs.Field("f18", 18) f19 = pcs.Field("f19", 19) f20 = pcs.Field("f20", 20) f21 = pcs.Field("f21", 21) f22 = pcs.Field("f22", 22) f23 = pcs.Field("f23", 23) f24 = pcs.Field("f24", 24) f25 = pcs.Field("f25", 25) f26 = pcs.Field("f26", 26) f27 = pcs.Field("f27", 27) f28 = pcs.Field("f28", 28) f29 = pcs.Field("f29", 29) f30 = pcs.Field("f30", 30) f31 = pcs.Field("f31", 31) f32 = pcs.Field("f32", 32) pcs.Packet.__init__(self, [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32], bytes = None) class boundsTestCase(unittest.TestCase): def test_field(self): ip = ipv4() assert (ip != None) self.assertRaises(pcs.FieldBoundsError, setattr, ip, 'version', 9999) def test_stringfield(self): ether = ethernet() self.assertRaises(pcs.FieldBoundsError, setattr, ether, 'src', "\x00\x00\x00\x00\x00\x00\x00") def test_lengthvaluefield(self): dns = dnsrr() self.assertRaises(pcs.FieldBoundsError, setattr, dns, 'name', "The walrus and the carpenter were walking close at hand. The wept like anything to see such quantities of sand. The Walrus and the Carpenter Were walking close at hand; They wept like anything to see Such quantities of sand: If this were only cleared away, They said, it would be grand! If seven maids with seven mops Swept it for half a year. Do you suppose, the Walrus said, That they could get it clear? I doubt it, said the Carpenter, And shed a bitter tear.The time has come the walrus said to speak of many things of shoes and ships and sealing wax and cabbages and Kings, and why the sea is boiling hot and whether pigs have whings. Caloo Callay or frabjous day for cabbages and kings?") def test_allbits(self): packet = boundaryPacket() for field in packet._layout: self.assertRaises(pcs.FieldBoundsError, setattr, packet, field.name, 2 ** field.width) self.assertRaises(pcs.FieldBoundsError, setattr, packet, field.name, -1) if __name__ == '__main__': unittest.main() pcs-0.6/tests/tcpv4test.py0000664000175000017500000002210611255512624015442 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: tcpv4test.py,v 1.2 2006/08/01 13:35:58 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on the IPv4 packet. # That is to say it first encodes a packet, then decodes it and makes # sure that the data matches. import unittest import sys from hexdumper import hexdumper if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import PcapConnector from pcs.packets.ipv4 import * from pcs.packets.tcp import tcp from pcs import inet_atol class tcpTestCase(unittest.TestCase): def test_tcpv4(self): # create one packet, copy its bytes, then compare their fields tcppacket = tcp() assert (tcppacket != None) tcppacket.sport = 51 tcppacket.dport = 50 tcppacket.sequence = 42 tcppacket.offset = 10 tcppacket.urgent = 1 tcppacket.ack = 1 tcppacket.push = 1 tcppacket.reset = 1 tcppacket.syn = 1 tcppacket.fin = 1 tcppacket.window = 1024 tcppacket.checksum = 0 # Create a packet to compare against tcpnew = tcp() tcpnew.decode(tcppacket.bytes) self.assertEqual(tcppacket.bytes, tcpnew.bytes, "bytes not equal") for field in tcppacket._fieldnames: self.assertEqual(getattr(tcppacket, field), getattr(tcpnew, field), ("%s not equal" % field)) def test_tcpv4_read(self): """This test reads from a pre-stored pcap file generated with tcpdump.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) self.assertEqual(tcppacket.sport, 53678, "source port not equal %d" % tcppacket.sport) self.assertEqual(tcppacket.dport, 80, "destination port not equal %d" % tcppacket.dport) self.assertEqual(tcppacket.sequence, 1351059655, "sequence number not equal %d" % tcppacket.sequence) self.assertEqual(tcppacket.ack_number, 0, "ack number not equal %d" % tcppacket.ack_number) self.assertEqual(tcppacket.offset, 11, "offset not equal %d" % tcppacket.offset) self.assertEqual(tcppacket.reserved, 0, "reserved not equal %d" % tcppacket.reserved) self.assertEqual(tcppacket.urgent, 0, "urgent not equal %d" % tcppacket.urgent) self.assertEqual(tcppacket.ack, 0, "ack not equal %d" % tcppacket.ack) self.assertEqual(tcppacket.push, 0, "push not equal %d" % tcppacket.push) self.assertEqual(tcppacket.reset, 0, "reset not equal %d" % tcppacket.reset) self.assertEqual(tcppacket.syn, 1, "syn not equal %d" % tcppacket.syn) self.assertEqual(tcppacket.fin, 0, "fin not equal %d" % tcppacket.fin) self.assertEqual(tcppacket.window, 65535, "window not equal %d" % tcppacket.window) self.assertEqual(tcppacket.checksum, 15295, "checksum not equal %d" % tcppacket.checksum) def test_tcpv4_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) tcp1 = tcp(ip.data.bytes) tcp2 = tcp(ip.data.bytes) assert (tcp1 != None) assert (tcp2 != None) #hd = hexdumper() #print hd.dump(tcp1.bytes) #print hd.dump(tcp2.bytes) # tcp1 should not equal tcp2, they are different instances, # and will therefore have different timestamps -- unless # we end up racing the system clock. self.assertNotEqual(tcp1, tcp2, "instances SHOULD be equal") self.assertEqual(tcp1.bytes, tcp2.bytes, "packet data SHOULD be equal") tcp1.dport = 0 self.assertNotEqual(tcp1.bytes, tcp2.bytes, "packet data SHOULD NOT be equal") def test_tcpv4_str(self): """Test the ___str__ method to make sure the correct values are printed.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) assert (tcppacket) # pre tcp options: #expected = "TCP\nsport 53678\ndport 80\nsequence 1351059655\nack_number 0\noffset 11\nreserved 0\nurgent 0\nack 0\npush 0\nreset 0\nsyn 1\nfin 0\nwindow 65535\nchecksum 15295\nurg_pointer 0\n" # post tcp options: expected = "TCP\nsport 53678\ndport 80\nsequence 1351059655\nack_number 0\noffset 11\nreserved 0\nurgent 0\nack 0\npush 0\nreset 0\nsyn 1\nfin 0\nwindow 65535\nchecksum 15295\nurg_pointer 0\n" \ "options [" \ "[Field: mss, Value: " \ "], " \ "[Field: nop, Value: 1], " \ "[Field: wscale, Value: " \ "], " \ "[Field: nop, Value: 1], " \ "[Field: nop, Value: 1], " \ "[Field: tstamp, Value: " \ "], " \ "[Field: sackok, Value: " \ "], " \ "[Field: end, Value: 0], " \ "[Field: end, Value: 0]" \ "]\n" gotttted = tcppacket.__str__() self.assertEqual(expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted)) def test_tcpv4_println(self): """Test the println method.""" file = PcapConnector("wwwtcp.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) tcppacket = tcp(ip.data.bytes) assert (tcppacket) # pre tcp options: #expected = "" # post tcp options: # XXX println() uses __repr__(), not __str__(). the rules for the # game "python" say we have to preserve the structure of # objects returned by __repr__(). expected = "], " \ "[Field: nop, Value: 1], " \ "[Field: wscale, Value: " \ "], " \ "[Field: nop, Value: 1], " \ "[Field: nop, Value: 1], " \ "[Field: tstamp, Value: " \ "], " \ "[Field: sackok, Value: " \ "], " \ "[Field: end, Value: 0], " \ "[Field: end, Value: 0]" \ "]>" # unusual naming to make it easier to spot deltas in an # 80 column display. gotttted = tcppacket.println() self.assertEqual(expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted)) if __name__ == '__main__': unittest.main() pcs-0.6/tests/dns.out0000664000175000017500000000021011255512624014435 0ustar andreasandreasÔò¡ÿÿ›JÒD;Å`` ¤ ìQìû=ERtÃ@f– ò8zB^xÆþ5>¶Çâmsvrfyahoocomhotspott-mobilecompcs-0.6/tests/printtest.py0000664000175000017500000001654511255512624015550 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ethertest.py,v 1.7 2006/07/13 10:05:40 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on an IP packet. That # is to say it first encodes a packet, then decodes is and makes sure # that the data matches. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import PcapConnector from pcs import PcapDumpConnector from pcs.packets.ethernet import * class etherTestCase(unittest.TestCase): def test_ethernet(self): # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 # Create a packet to compare against ethernew = ethernet() ethernew.decode(ether.bytes) self.assertEqual(ether.bytes, ethernew.bytes, "bytes not equal") self.assertEqual(ether.src, ethernew.src, "sources not equal ether %s ethernew %s" % (ether.src, ethernew.src)) self.assertEqual(ether.dst, ethernew.dst, "destinations not equal ether %s ethernew %s" % (ether.dst, ethernew.dst)) self.assertEqual(ether.type, ethernew.type, "types not equal ether %s ethernew %s" % (ether.type, ethernew.type)) def test_ethernet_eq(self): "Test whether the eq function works for ethernet" ether = ethernet() assert (ether != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 # Create a packet to compare against ethernew = ethernet() ethernew.decode(ether.bytes) self.assertEqual(ether.bytes, ethernew.bytes, "bytes not equal") self.assertEqual(ether.src, ethernew.src, "sources not equal ether %s ethernew %s" % (ether.src, ethernew.src)) self.assertEqual(ether.dst, ethernew.dst, "destinations not equal ether %s ethernew %s" % (ether.dst, ethernew.dst)) self.assertEqual(ether.type, ethernew.type, "types not equal ether %s ethernew %s" % (ether.type, ethernew.type)) self.assertEqual(ether, ethernew, "ether != to ethernew but should be") def test_ethernet_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = PcapConnector("etherping.out") # packet = file.read() # ether = ethernet(packet) ether = file.readpkt() assert (ether != None) self.assertEqual(ether.dst, "\x00\x10\xdb\x3a\x3a\x77", "dst not equal %s" % ether.src) self.assertEqual(ether.src, "\x00\x0d\x93\x44\xfa\x62", "src not equal %s" % ether.dst) self.assertEqual(ether.type, 0x800, "type not equal %d" % ether.type) def test_ethernet_write(self): """This test writes a fake ethernet packet to a dump file.""" from pcs.pcap import DLT_EN10MB file = PcapDumpConnector("etherdump.out", DLT_EN10MB) # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 file.write(ether.bytes) def test_ethernet_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("etherping.out") packet = file.read() ether1 = ethernet(packet[0:file.dloff]) ether2 = ethernet(packet[0:file.dloff]) assert (ether1 != None) assert (ether2 != None) self.assertEqual(ether1, ether2, "packets should be equal but are not") ether1.dst = "\xff\xff\xff\xff\xff\xff" self.assertNotEqual(ether1, ether2, "packets compare equal but should not") def test_ethernet_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on an ethernet interface and tests the println method to make sure the correct values are printed.""" file = PcapConnector("etherping.out") packet = file.read() ether = ethernet(packet[0:file.dloff]) assert (ether != None) test_string = "Ethernet\ndst: 0:10:db:3a:3a:77\nsrc: 0:d:93:44:fa:62\ntype: 0x800" string = ether.__str__() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) def test_ethernet_println(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on an ethernet interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("etherping.out") packet = file.read() ether = ethernet(packet[0:file.dloff]) assert (ether != None) test_string = "" string = ether.println() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) if __name__ == '__main__': unittest.main() pcs-0.6/tests/etherdump.out0000644000175000017500000000006611255517142015655 0ustar andreasandreasÔò¡ÿÿbž¶Jÿÿÿÿÿÿpcs-0.6/tests/connectortest.py0000664000175000017500000001420011255512624016370 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: connectortest.py,v 1.2 2006/08/01 13:35:58 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on the Connector classes # provided with PCS. import unittest import sys from socket import * if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs.packets.ethernet import ethernet from pcs.packets.localhost import localhost from pcs.packets.ipv4 import ipv4 from pcs.packets.icmpv4 import icmpv4 from pcs.packets.icmpv4 import icmpv4echo from pcs import * class pcapTestCase(unittest.TestCase): def test_pcap_file(self): file = PcapConnector("loopping.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) self.assertEqual(ip.version, 4, "version not equal %d" % ip.version) self.assertEqual(ip.hlen, 5, "hlen not equal %d" % ip.hlen) self.assertEqual(ip.tos, 0, "tos not equal %d" % ip.tos) self.assertEqual(ip.length, 84, "length not equal %d" % ip.length) self.assertEqual(ip.id, 59067, "id not equal %d" % ip.id) self.assertEqual(ip.flags, 0, "flags not equal %d" % ip.flags) self.assertEqual(ip.offset, 0, "offset not equal %d" % ip.offset) self.assertEqual(ip.ttl, 64, "ttl not equal %d" % ip.ttl) self.assertEqual(ip.protocol, 1, "protocol not equal %d" % ip.protocol) self.assertEqual(ip.src, inet_atol("127.0.0.1"), "src not equal %d" % ip.src) self.assertEqual(ip.dst, inet_atol("127.0.0.1"), "dst not equal %d" % ip.dst) def test_pcap_live(self): """Test live injection and reception. This test requires threads and must be run as root to succeed.""" import threading e = ethernet() assert (e != None) e.src = "\x00\xbd\x03\x07\xfa\x00" e.dst = "\x00\xbd\x03\x07\xfa\x00" e.type = 0x0800 # Create a vanilla ping packet ip = ipv4() ip.version = 4 ip.hlen = 5 ip.tos = 0 ip.length = 64 ip.id = 1 ip.flags = 0 ip.offset = 0 ip.ttl = 64 ip.protocol = IPPROTO_ICMP ip.src = inet_atol("192.0.2.1") ip.dst = inet_atol("192.0.2.1") icmp = icmpv4() icmp.type = 8 icmp.code = 0 echo = icmpv4echo() echo.id = 54321 echo.seq = 12345 ip.length = len(ip.bytes) + len(icmp.bytes) + len(echo.bytes) packet = Chain([e, ip, icmp, echo]) packet.calc_checksums() packet.encode() import os uname = os.uname()[0] if uname == "FreeBSD": devname = "edsc0" elif uname == "Linux": devname = "lo" elif uname == "Darwin": devname = "en0" else: print "unknown host os %s" % uname return wfile = PcapConnector(devname) rfile = PcapConnector(devname) rfile.setfilter("icmp") count = wfile.write(packet.bytes, 42) assert (count == 42) got = ethernet(rfile.read()) ip = got.data ping = ip.data self.assertEqual(ping, icmp) def test_pcap_write(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" from pcs.pcap import DLT_NULL # Create a vanilla ping packet ip = ipv4() ip.version = 4 ip.hlen = 5 ip.tos = 0 ip.length = 64 ip.id = 1 ip.flags = 0 ip.offset = 0 ip.ttl = 64 ip.protocol = IPPROTO_ICMP ip.src = inet_atol("127.0.0.1") ip.dst = inet_atol("127.0.0.1") icmp = icmpv4() icmp.type = 8 icmp.code = 0 echo = icmpv4echo() echo.id = 32767 echo.seq = 1 lo = localhost() lo.type = 2 packet = Chain([lo, ip, icmp, echo]) outfile = PcapDumpConnector("pcaptest.dump", DLT_NULL) outfile.write(packet.bytes) outfile.close() infile = PcapConnector("pcaptest.dump") packet = infile.read() ipnew = ipv4(packet[infile.dloff:len(packet)]) assert (ip != None) assert (ipnew != None) self.assertEqual(ip, ipnew, "packets should be equal but are not") if __name__ == '__main__': unittest.main() pcs-0.6/tests/tlvtest.py0000664000175000017500000000665411255512624015221 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: Bruce M. Simpson # # Description: Type/Length/Value test import unittest import sys from hexdumper import hexdumper if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs class testPacket(pcs.Packet): """Define a packet containing a TLV field for use in testing.""" _layout = pcs.Layout() def __init__(self, bytes = None): f1 = pcs.Field("f1", 32) f2 = pcs.TypeLengthValueField("f2", pcs.Field("t", 8), pcs.Field("l", 8), pcs.StringField("v", 10 * 8)) pcs.Packet.__init__(self, [f1, f2], bytes = None) def __str__(self): """Walk the entire packet and pretty print the values of the fields.""" retval = "TEST\n" for field in self._layout: retval += "%s %s\n" % (field.name, self.__dict__[field.name]) return retval class tlvTestCase(unittest.TestCase): def test_tlv(self): """Create one packet containing a TLV field.""" data = "\x12\x34\xAB\xCD\xAB\x0c\x66\x6F" \ "\x6F\x62\x61\x72\x00\x00\x00\x00" # XXX The length of the f2 field is filled out with # the maximum length of the value field, NOT its packed # length. LengthValueField also has this issue. # Also, the TLV fields are ambiguous as to whether the # length represents bits or bytes. # IP protocols are usually byte or 32-bit word aligned. packet = testPacket() packet.f1 = 0x1234abcd packet.f2.type.value = 0xab packet.f2.length.value = len("foobar") packet.f2.value.value = "foobar" packet.encode() #hd = hexdumper() #print hd.dump(packet.bytes) #print hd.dump(data) self.assertEqual(packet.bytes, data, \ "packets should be equal but are not") if __name__ == '__main__': unittest.main() pcs-0.6/tests/make.out0000664000175000017500000001520711255521625014603 0ustar andreasandreasfor file in boundstest.py chaintest.py connectortest.py copytest.py dhcpv4test.py divtest.py dnstest.py ethertest.py icmpv4test.py igmpv3test.py ipv4test.py ipv6test.py maptest.py optiontest.py printtest.py sctptest.py tcpv4test.py tlvtest.py udpv4test.py; do\ echo Running test $file; \ sudo python $file; \ done Running test boundstest.py Traceback (most recent call last): File "boundstest.py", line 49, in import pcs File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test chaintest.py Traceback (most recent call last): File "chaintest.py", line 48, in import pcs File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test connectortest.py Traceback (most recent call last): File "connectortest.py", line 51, in from pcs.packets.ethernet import ethernet File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test copytest.py Traceback (most recent call last): File "copytest.py", line 51, in import pcs File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test dhcpv4test.py Traceback (most recent call last): File "dhcpv4test.py", line 49, in from pcs import inet_atol File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test divtest.py Traceback (most recent call last): File "divtest.py", line 48, in import pcs File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test dnstest.py Traceback (most recent call last): File "dnstest.py", line 51, in from pcs.packets.dns import * File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test ethertest.py Traceback (most recent call last): File "ethertest.py", line 50, in from pcs import PcapConnector File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test icmpv4test.py Traceback (most recent call last): File "icmpv4test.py", line 50, in from pcs.packets.ethernet import ethernet File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test igmpv3test.py Traceback (most recent call last): File "igmpv3test.py", line 13, in from pcs.packets.ethernet import * File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test ipv4test.py Traceback (most recent call last): File "ipv4test.py", line 50, in from pcs import PcapConnector File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test ipv6test.py Traceback (most recent call last): File "ipv6test.py", line 49, in from pcs import PcapConnector File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test maptest.py Traceback (most recent call last): File "maptest.py", line 48, in from pcs import PcapConnector File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test optiontest.py Traceback (most recent call last): File "optiontest.py", line 49, in import pcs File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test printtest.py Traceback (most recent call last): File "printtest.py", line 50, in from pcs import PcapConnector File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test sctptest.py Traceback (most recent call last): File "sctptest.py", line 47, in from pcs import PcapConnector File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test tcpv4test.py Traceback (most recent call last): File "tcpv4test.py", line 50, in from pcs import PcapConnector File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test tlvtest.py Traceback (most recent call last): File "tlvtest.py", line 47, in import pcs File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf Running test udpv4test.py Traceback (most recent call last): File "udpv4test.py", line 50, in from pcs.packets.ethernet import * File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in import pcs.pcap as pcap File "bpf.pxd", line 34, in pcap (pcs/pcap/pcap.c:4840) ImportError: No module named bpf gmake: *** [test] Error 1 pcs-0.6/tests/ethertest.py0000664000175000017500000001654411255512624015522 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ethertest.py,v 1.7 2006/07/13 10:05:40 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on an IP packet. That # is to say it first encodes a packet, then decodes is and makes sure # that the data matches. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import PcapConnector from pcs import PcapDumpConnector from pcs.packets.ethernet import * class etherTestCase(unittest.TestCase): def test_ethernet(self): # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 # Create a packet to compare against ethernew = ethernet() ethernew.decode(ether.bytes) self.assertEqual(ether.bytes, ethernew.bytes, "bytes not equal") self.assertEqual(ether.src, ethernew.src, "sources not equal ether %s ethernew %s" % (ether.src, ethernew.src)) self.assertEqual(ether.dst, ethernew.dst, "destinations not equal ether %s ethernew %s" % (ether.dst, ethernew.dst)) self.assertEqual(ether.type, ethernew.type, "types not equal ether %s ethernew %s" % (ether.type, ethernew.type)) def test_ethernet_eq(self): "Test whether the eq function works for ethernet" ether = ethernet() assert (ether != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 # Create a packet to compare against ethernew = ethernet() ethernew.decode(ether.bytes) self.assertEqual(ether.bytes, ethernew.bytes, "bytes not equal") self.assertEqual(ether.src, ethernew.src, "sources not equal ether %s ethernew %s" % (ether.src, ethernew.src)) self.assertEqual(ether.dst, ethernew.dst, "destinations not equal ether %s ethernew %s" % (ether.dst, ethernew.dst)) self.assertEqual(ether.type, ethernew.type, "types not equal ether %s ethernew %s" % (ether.type, ethernew.type)) self.assertEqual(ether, ethernew, "ether != to ethernew but should be") def test_ethernet_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = PcapConnector("etherping.out") # packet = file.read() # ether = ethernet(packet) ether = file.readpkt() assert (ether != None) self.assertEqual(ether.dst, "\x00\x10\xdb\x3a\x3a\x77", "dst not equal %s" % ether.src) self.assertEqual(ether.src, "\x00\x0d\x93\x44\xfa\x62", "src not equal %s" % ether.dst) self.assertEqual(ether.type, 0x800, "type not equal %d" % ether.type) def test_ethernet_write(self): """This test writes a fake ethernet packet to a dump file.""" from pcs.pcap import DLT_EN10MB file = PcapDumpConnector("etherdump.out", DLT_EN10MB) # create one packet, copy its bytes, then compare their fields ether = ethernet() assert (ethernet != None) ether.src = "\x00\x00\x00\x00\x00\x00" ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 2048 file.write(ether.bytes) def test_ethernet_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("etherping.out") packet = file.read() ether1 = ethernet(packet[0:file.dloff]) ether2 = ethernet(packet[0:file.dloff]) assert (ether1 != None) assert (ether2 != None) self.assertEqual(ether1, ether2, "packets should be equal but are not") ether1.dst = "\xff\xff\xff\xff\xff\xff" self.assertNotEqual(ether1, ether2, "packets compare equal but should not") def test_ethernet_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on an ethernet interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("etherping.out") packet = file.read() ether = ethernet(packet[0:file.dloff]) assert (ether != None) test_string = "Ethernet\ndst: 0:10:db:3a:3a:77\nsrc: 0:d:93:44:fa:62\ntype: 0x800" string = ether.__str__() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) def test_ethernet_println(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on an ethernet interface and tests the println method to make sure the correct values are printed.""" file = PcapConnector("etherping.out") packet = file.read() ether = ethernet(packet[0:file.dloff]) assert (ether != None) string = ether.println() test_string = "" self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) if __name__ == '__main__': unittest.main() pcs-0.6/tests/ktrace.out0000600000175000017500000300230311255525232015117 0ustar andreasandreas­Þ~ktracešª¶Jb‡-­Þ ­Þ~ktracešª¶JÉ ‡;°âÿÿÿ0èÿÿÿHèÿÿÿ­Þ~ktracešª¶Jó ‡/home/gnn/bin/python2.6­Þ~ktracešª¶Je ‡; ­Þ~ktracešª¶Jo ‡;°âÿÿÿ0èÿÿÿHèÿÿÿ­Þ~ktracešª¶J• ‡/bin/python2.6­Þ~ktracešª¶Jï ‡; ­Þ~ktracešª¶Jú ‡;°âÿÿÿ0èÿÿÿHèÿÿÿ­Þ~ktracešª¶J ‡/sbin/python2.6­Þ~ktracešª¶Jy ‡; ­Þ~ktracešª¶Jƒ ‡;°âÿÿÿ0èÿÿÿHèÿÿÿ­Þ~ktracešª¶J¦ ‡/usr/bin/python2.6­Þ~ktracešª¶J ‡; ­Þ~ktracešª¶J ‡;°âÿÿÿ0èÿÿÿHèÿÿÿ­Þ~ktracešª¶J2 ‡/usr/sbin/python2.6­Þ~ktracešª¶J ‡; ­Þ~ktracešª¶Jž ‡;°âÿÿÿ0èÿÿÿHèÿÿÿ­Þ~ktracešª¶JÀ ‡/usr/X11/bin/python2.6­Þ~ktracešª¶J ‡; ­Þ~ktracešª¶J ‡;°âÿÿÿ0èÿÿÿHèÿÿÿ­Þ~ktracešª¶J? ‡/usr/local/bin/python2.6­Þ~ktracešª¶J ‡/libexec/ld-elf.so.1­Þ~python2.6šª¶JÒ‡;8­Þ~python2.6šª¶J!‡ÊÐßÿÿÿìßÿÿÿàßÿÿÿ ­Þ~python2.6šª¶J7‡kern.osreldate­Þ~python2.6šª¶JB‡Ê8­Þ~python2.6šª¶Jœ‡Ý ÿÿÿÿ­Þ~python2.6šª¶J¨‡Ýc­Þ~python2.6šª¶Jë‡Ic ­Þ~python2.6šª¶J÷‡I8­Þ~python2.6šª¶J‡Ê@àÿÿÿ(³s8àÿÿÿ ­Þ~python2.6šª¶J‡hw.pagesize­Þ~python2.6šª¶J‡Ê8­Þ~python2.6šª¶J'‡Ý€ÿÿÿÿ­Þ~python2.6šª¶J2‡Ýc­Þ~python2.6šª¶JX‡ý­Þ~python2.6šª¶Ja‡ý ­Þ~python2.6šª¶JŸ‡’Öb¶­Þ~python2.6šª¶J¬‡/etc/libmap.conf­Þ~python2.6šª¶Jć ­Þ~python2.6šª¶JÓ‡Çb/­Þ~python2.6šª¶JÞ‡/var/run/ld-elf.so.hints­Þ~python2.6šª¶Jð‡ ­Þ~python2.6šª¶Jù‡pÝÿÿÿ€ˆ­Þ~python2.6šª¶J‡Ehnt€-,­Þ~python2.6šª¶J‡€ ­Þ~python2.6šª¶J"‡Þ€­Þ~python2.6šª¶J,‡Þ€ ­Þ~python2.6šª¶J5‡@c-5­Þ~python2.6šª¶JA‡/lib:/usr/lib:/usr/lib/compat:/usr/local/lib­Þ~python2.6šª¶J™‡-­Þ~python2.6šª¶J£‡­Þ~python2.6šª¶J²‡­Þ~python2.6šª¶JLJ!Pc­Þ~python2.6šª¶JÔ‡/lib/libutil.so.8­Þ~python2.6šª¶Jå‡! ­Þ~python2.6šª¶J c²s­Þ~python2.6šª¶Jù‡/lib/libutil.so.8­Þ~python2.6šª¶J‡­Þ~python2.6šª¶J‡½ðßÿÿÿ}­Þ~python2.6šª¶J‡statY´$Ø\ª¶J%µJ%µJ`õ|%µJ­Þ~python2.6šª¶J&‡½ ­Þ~python2.6šª¶J/‡à¡s­Þ~python2.6šª¶JI‡ELF >P@`ï@8@PÊPÊÐÐÐ('@á@á@áPåtdHÊHÊHÊ |îdÔœ9ù÷çøWÐï†èRVÅ…Ä+EÉnÿé4¿Ás‘¯:ñótÕ܈ûžQ›ÀþǾªä}â*8µ–Æ2à×ÃÒ°ƒírx¡™ú ;€w»”¸bôü‰zÙ¤B¶mØÓãÛŒòì{‡IÖð´²ý·vÏlæ«=Tßê?ÊM‹"Hë7•öp—¥Ñe~ŸáÌÝL“åõ„c¦®5>KJNCZa&(oi1-O</S$qŽ#.6PG\%!¬)]Fu,Š­g§¹½D¨Ayš±Uh^3'kX[¼YjÞ Ë³˜©ºÚ@Σf0¢Í’‚_È` h @"l+€-À- 4E ,E P ø½ ¾ HÊÐÐÓ@áÐâàâðâøâéîi  ÐxGà>`³åí ð»9½ PT ‰s @–hØG2ž£ PSø/ ‚ˆ@š*¨ ð^åœ* °m}ï àwåá÷…† pgu´…ñÿ@áÕË1 P¿Åp `{f¾ ðvé±YU “Ø àr¨4vUÈ6 €yÇè>:W Ðo£ Ð{_† "1[­Þ~python2.6šª¶Jž‡8­Þ~python2.6šª¶J¨‡Ýÿÿÿÿ­Þ~python2.6šª¶J³‡Ý€t8­Þ~python2.6šª¶J¼‡Ý€tЭÞ~python2.6šª¶Jé‡Ý€t8­Þ~python2.6šª¶Jó‡ÝP… ЭÞ~python2.6šª¶J ‡ÝP… ­Þ~python2.6šª¶J7‡Jp…­Þ~python2.6šª¶JC‡J­Þ~python2.6šª¶JT‡­Þ~python2.6šª¶J½‡­Þ~python2.6šª¶Jȇ!Pc­Þ~python2.6šª¶JÕ‡/lib/libm.so.5­Þ~python2.6šª¶Jç‡! ­Þ~python2.6šª¶Jð‡à c²s­Þ~python2.6šª¶Jû‡/lib/libm.so.5­Þ~python2.6šª¶J ‡­Þ~python2.6šª¶J‡½ðßÿÿÿ}­Þ~python2.6šª¶J‡statY$ˆª¶JÖÿ´JÖÿ´J Öÿ´J­Þ~python2.6šª¶J(‡½ ­Þ~python2.6šª¶J1‡à¡s­Þ~python2.6šª¶Jš‡ELF >`8@À@8@„ЄÐÐÐШ°øçøçøç°°Påtd|Ð|Ð|ÐÅíq¿¬±P{øÕþòpùäUŒõ[ñÓÌI&ê«Å»û§¶xz­o¢¦02ïðµóéÄÂàÿ´ƒèÑj–fÛ³t÷¼‡eÞb_Nßö¾cÏ©¯å£²ÈãúœÆ°›(ˆôáâFžý<…lE~g/)ª¸.šì×Z!rÒÎJ}¤‹®ÙüÔÝ €æîÐ¥ÉÚË“"%9B*@+G5H7]M- LCTh3w$kin#A=ODy^>Ž16K„\’d¡Ÿ‰4”W•†a—‚¹SXsVÀ`½˜,vÁQu|ÇRÍ™ÜØ¨Yº‘Ã'ëm:çŠÊ;8·Ö? @X &(À(à(8+ 3 3 `8 Ø€ |ÐÐ€Ñøç¨é¸éÈéÐé8í [{v ð:9 0@«ã `ö¹= Ð}ׯ : üF1 À¤ u˜ €ƒO. €!Å МÞÿ 0"_g p: °c  ਠH °2•  /‘² <î àý×¥ p< , 09[  ÀZ 0pk à:  ³òm9¹ rV 0uf 0:# t¬ï Ðc¿  <Û) €LX, `{j* Ðw˜a àw^à 0ÝP´ €:Ô Pî•"1R °©9† À‚ £ž P?è  ;m© Ç Žñÿ /›÷ @by4 ­Ö  ÀtAR  :Ñ `̰å@$ ÐÓÌ 0•½R Ð<u °n­Þ~python2.6šª¶Jë‡8­Þ~python2.6šª¶Jö‡Ýðÿÿÿÿ­Þ~python2.6šª¶J‡Ý€…8­Þ~python2.6šª¶J ‡Ý€…à­Þ~python2.6šª¶JO‡Ý€…8­Þ~python2.6šª¶JY‡ÝP— ЭÞ~python2.6šª¶Jn‡ÝP—­Þ~python2.6šª¶JŸ‡­Þ~python2.6šª¶J«‡­Þ~python2.6šª¶Jµ‡!Pc­Þ~python2.6šª¶JÁ‡/lib/libthr.so.3­Þ~python2.6šª¶JÓ‡! ­Þ~python2.6šª¶J݇ !c²s­Þ~python2.6šª¶Jþ‡/lib/libthr.so.3­Þ~python2.6šª¶J ‡­Þ~python2.6šª¶J‡½ðßÿÿÿ}­Þ~python2.6šª¶J"‡statY¶$_ª¶JeµJeµJb´eµJ­Þ~python2.6šª¶J+‡½ ­Þ~python2.6šª¶J3‡à¡s­Þ~python2.6šª¶J¢‡ELF >°s@P\@8@(( ( ( (ð*€QXMXMXMÀÀPåtdü'ü'ü'ý½Ì0»õ…uöØëOv¥†¡§ÖZîÜÀæçK¬æÉåa.ÚêwA´¾BÍ/ñS˜â«!ò{¿óÿÇ)2nìÜfdªêÐÊŽõl±¥\]^©$¯àtº·`äè+Ÿ:ƒï 3hßÂÌ‹Q;ÁúžrTô­:à”ˆËd~“yÄs¾Ô¯x˜&Α7ü•ÕÈÆ!ðf`Û¶ÑÐQºVÞÎ-ûøø÷›@ù¼µB„šED°(™ÕéIã²1o€ŽÓ?náíŠ^q¦F%¨[óNé×ÓÝ8>ÃrUpJmP½ (4#,+GR2&[%]tlS)1gWŠv…=*“6Cƒ¡"Ey}Œbx|8•9s‘Á„®—ÈK‰~-¬›Ÿ°³3w¼?ËOÏmÅqµHÙ/Ap÷jò¹FßUZìÒç«0ÍeÑ5\ÔX Øëž‹cûñï¤Ä<Þ.,áJã'‚‡â@ù Ê±ð¢€L·ú YèR¨özÀä'c$=¸>CPœÖW"åÃô4j_ub×}»k –‚ü 69X#¿7HÇ<Lh—*¤za|GMo;Y’£¢§™Ú©œ–Æ­Å_²†³V‰{ k¸Éiˆe5¦TþDí”ݹϣҶý‡’IŒgš ´®iªMNÙÛî 8 ð<&Q UÈUVÈb Ðl äl °s ˆ"  "ü' (0-XMO0O@OHO€S5" w  ¥ež €ŒÒ  Î _  Ç" €”­Þ~python2.6šª¶Jø‡8­Þ~python2.6šª¶J‡Ý€ÿÿÿÿ­Þ~python2.6šª¶J ‡Ýp—8­Þ~python2.6šª¶J‡Ýp—0­Þ~python2.6šª¶JD‡Ýp—8­Þ~python2.6šª¶JN‡Ý¨@ ­Þ~python2.6šª¶Jc‡Ý¨ ­Þ~python2.6šª¶J‡JШ ­Þ~python2.6šª¶J˜‡J­Þ~python2.6šª¶J«‡­Þ~python2.6šª¶J·‡­Þ~python2.6šª¶JÁ‡!Pc­Þ~python2.6šª¶J͇/lib/libc.so.7­Þ~python2.6šª¶J݇! ­Þ~python2.6šª¶Jꇠ!c²s­Þ~python2.6šª¶Jö‡/lib/libc.so.7­Þ~python2.6šª¶J‡­Þ~python2.6šª¶JS‡½ðßÿÿÿ}­Þ~python2.6šª¶J^‡statY°$@‹šª¶J‘ÿ´J‘ÿ´JÀn` ‘ÿ´J­Þ~python2.6šª¶Jg‡½ ­Þ~python2.6šª¶Jq‡à¡s­Þ~python2.6šª¶J‡ELF > Ý@@f@8@"!ÌýÌý àȆ¨½¨½¨½€€p}p}p}PåtdÄýÄýÄý¥ F3êùÆ í-Ž0 Ãä@ ÑË x › m$ Öe d ¨ âB€e ÍjÔØŠ ‚ Ð: \yR¯sv îßQ õ¯†m aq? ÄžW LŒ}_• B²î11Ê—Á»à îç” æ ó '¡­ È Q [ ÚD þ³" êè3Ž pÇή éS#oŽTîµ±(a ‡ C } 8ÛŽ `I/Ê QÞj§+t)H‚º…[ H´=s8N z‚¸^‚À~% áž  ©) Ý{ Œ Ç‹eÙ†t QÉ ð•ÎK*o@8÷ € 9ç–ÐT ¤¯Š r¦´Üˆ; _ë«hü ÈGˆk>> 5¶ ÍD÷V= < ±pUö Oh' ,yÑ~´Ð †ù ÀOMNü Ñ Tųj¦C y ý¢\ž. W „, ½ÿO LMÉ< ¥ñ DÓ¾ ÌÓ4 ¼+ ]É´ Ôi%ô ›U þF®t d©‰ ÷½aÑx §z / _4v L8ë¹ ÞþO7 ±¬ îP 0 gг éEÔÛ* sm" › 9uE å ~ ú’¶q ¡rC^€¸ Ï ¾xDC¥s ›ØÓ ià€Îª p\J ; óV ‘ oYY7 3“Æ\¨‚  o¿@¤ %» ö]Ý« 뉫¼%õV¨ÈG2| S xÎ Ç ;ºn“ ÏË,Þ“#c L „æ: ÆGB ¼øÂ£k ¥ ±I ¤ê[ ¼u 鸭?¥ ›u ° ÝI ØœÛ „ 4‡rÁM ð: Ê·á $ÜüÞ Ã' PÒ ¢  ÙgÆK Ô »Ý ’`ÔÙýã­s ˜‡ç X <íú‡¢î øz¤ x@ w AÀÑr–ˆË!F Ò\„:Sd 7>æÕ<fkmûO â5  ­…E ‹ Ò3 £ ñ žÆ’˜ b -# Ìœh] ævb~ v ù°>Áz*W'ågãà2N€ à >Z Ç úsýèÙçmh ôÓš 8ß~m ™Š! ß ÍT â‘ãÀ £t —?ûŠ\Þp… ­Þ~python2.6šª¶Jà‡8­Þ~python2.6šª¶Jë‡Ýÿÿÿÿ­Þ~python2.6šª¶J÷‡Ýð¨8­Þ~python2.6šª¶J‡Ýð¨­Þ~python2.6šª¶J‡Ýð¨8­Þ~python2.6šª¶J‡Ýð¸ð­Þ~python2.6šª¶JO‡Ý𸠭Þ~python2.6šª¶Jh‡Jຠ­Þ~python2.6šª¶Js‡J­Þ~python2.6šª¶J¯‡­Þ~python2.6šª¶J»‡­Þ~python2.6šª¶J凥Ààÿÿÿ­Þ~python2.6šª¶J8­Þ~python2.6šª¶Jø‡Ý Uÿÿÿÿ­Þ~python2.6šª¶J‡Ýc­Þ~python2.6šª¶J ‡Ic U­Þ~python2.6šª¶J‡I8­Þ~python2.6šª¶J)‡Ýÿÿÿÿ­Þ~python2.6šª¶J4‡Ýc­Þ~python2.6šª¶J‡Ic­Þ~python2.6šª¶Ja‡I8­Þ~python2.6šª¶Jp‡Ýÿÿÿÿ­Þ~python2.6šª¶J{‡Ýc­Þ~python2.6šª¶J¨‡Ic­Þ~python2.6šª¶Jì‡I8­Þ~python2.6šª¶Jú‡ÝÐÿÿÿÿ­Þ~python2.6šª¶J‡Ýc­Þ~python2.6šª¶J¶‡IcЭÞ~python2.6šª¶Jü‡I8­Þ~python2.6šª¶J‡ÝPªÿÿÿÿ­Þ~python2.6šª¶J‡Ýc­Þ~python2.6šª¶Já ‡IcPª­Þ~python2.6šª¶J=!‡I ­Þ~python2.6šª¶J¥!‡Tà sàÿÿÿ­Þ~python2.6šª¶J¯!‡T ­Þ~python2.6šª¶J¹!‡Tð s­Þ~python2.6šª¶JÂ!‡T8­Þ~python2.6šª¶J"‡Ê`àÿÿÿà7»Xàÿÿÿ ­Þ~python2.6šª¶J"‡kern.arandom­Þ~python2.6šª¶J."‡Ê ­Þ~python2.6šª¶J8"‡Tà s`àÿÿÿ­Þ~python2.6šª¶JA"‡T ­Þ~python2.6šª¶JJ"‡Tð s­Þ~python2.6šª¶JS"‡T­Þ~python2.6šª¶JÂ"‡­Þ~python2.6šª¶JË"‡~8­Þ~python2.6šª¶Jç"‡Ê@àÿÿÿpé¨Hàÿÿÿ ­Þ~python2.6šª¶Jó"‡kern.usrstack­Þ~python2.6šª¶Jþ"‡Ê8­Þ~python2.6šª¶J,#‡ÊÐßÿÿÿ`ßÿÿÿÈßÿÿÿ픘  ­Þ~python2.6šª¶J8#‡sysctl.name2oid­Þ~python2.6šª¶JL#‡Ê8­Þ~python2.6šª¶JU#‡Ê`ßÿÿÿhبHàÿÿÿ ­Þ~python2.6šª¶Jb#‡kern.smp.cpus­Þ~python2.6šª¶Jl#‡Ê8­Þ~python2.6šª¶Jœ#‡ÊàÿÿÿøJ¼øßÿÿÿ ­Þ~python2.6šª¶J¼#‡hw.pagesize­Þ~python2.6šª¶JÉ#‡Ê8­Þ~python2.6šª¶J$‡ÊPÛÿÿÿ¨)»HÛÿÿÿ ­Þ~python2.6šª¶J$‡hw.ncpu­Þ~python2.6šª¶J$‡Ê ­Þ~python2.6šª¶J-$‡:L¸pÛÿÿÿ­Þ~python2.6šª¶J:$‡/etc/malloc.conf­Þ~python2.6šª¶JI$‡:­Þ~python2.6šª¶Jt$‡ý­Þ~python2.6šª¶J}$‡ý­Þ~python2.6šª¶J»$‡p­Þ~python2.6šª¶JÇ$‡8­Þ~python2.6šª¶Jó$‡ÊÝÿÿÿ¬Ýÿÿÿ Ýÿÿÿ ­Þ~python2.6šª¶J=%‡kern.osreldate­Þ~python2.6šª¶JH%‡Ê8­Þ~python2.6šª¶JT%‡Ýÿÿÿÿ­Þ~python2.6šª¶J`%‡Ý€¼8­Þ~python2.6šª¶Ji%‡Ý€Ì€ÿÿÿÿ­Þ~python2.6šª¶Jt%‡Ý€Ì­Þ~python2.6šª¶J%‡I€¼€­Þ~python2.6šª¶J‘%‡I­Þ~python2.6šª¶J&‡°À!À­Þ~python2.6šª¶J &‡°8­Þ~python2.6šª¶J&‡Ýð¿ÿÿÿÿÿÿ­Þ~python2.6šª¶J"&‡Ýð¿ÿÿ­Þ~python2.6šª¶J0&‡Ð‡5•˜­Þ~initial threadšª¶J9&‡Ð ­Þ~initial threadšª¶JG&‡Ò‡ðßÿÿÿ­Þ~initial threadšª¶JQ&‡Ò­Þ~initial threadšª¶Jx&‡¥àÿÿÿ­Þ~initial threadšª¶J&‡¥ ­Þ~initial threadšª¶JŒ&‡T0àÿÿÿ àÿÿÿ­Þ~initial threadšª¶J•&‡T ­Þ~initial threadšª¶J &‡  ðßÿÿÿ­Þ~initial threadšª¶Jª&‡  ­Þ~initial threadšª¶J³&‡T àÿÿÿ­Þ~initial threadšª¶J»&‡T ­Þ~initial threadšª¶JÄ&‡Tà s`àÿÿÿ­Þ~initial threadšª¶J'‡T ­Þ~initial threadšª¶J'‡Tð s­Þ~initial threadšª¶J$'‡T ­Þ~initial threadšª¶J1'‡Tà s`àÿÿÿ­Þ~initial threadšª¶J:'‡T ­Þ~initial threadšª¶JC'‡Tð s­Þ~initial threadšª¶JL'‡T ­Þ~initial threadšª¶J['‡Tà s`àÿÿÿ­Þ~initial threadšª¶Jd'‡T ­Þ~initial threadšª¶Jm'‡Tð s­Þ~initial threadšª¶Jv'‡T ­Þ~initial threadšª¶JÑ'‡6t,@æÿÿÿ­Þ~initial threadšª¶Jß'‡6­Þ~initial threadšª¶JP1‡½påÿÿÿ}­Þ~initial threadšª¶J]1‡statÿ^!é^™ª¶J™ª¶J™ª¶Jÿÿÿÿÿÿÿÿ­Þ~initial threadšª¶Jg1‡½­Þ~initial threadšª¶Jx1‡½ äÿÿÿ}­Þ~initial threadšª¶Jƒ1‡statÿ^!é^™ª¶J™ª¶J™ª¶Jÿÿÿÿÿÿÿÿ­Þ~initial threadšª¶JŒ1‡½­Þ~initial threadšª¶J–1‡½ äÿÿÿ}­Þ~initial threadšª¶J 1‡statÿ^!é^™ª¶J™ª¶J™ª¶Jÿÿÿÿÿÿÿÿ­Þ~initial threadšª¶J©1‡½­Þ~initial threadšª¶J²1‡½ äÿÿÿ}­Þ~initial threadšª¶J 2‡statÿ^!é^™ª¶J™ª¶J™ª¶Jÿÿÿÿÿÿÿÿ­Þ~initial threadšª¶J2‡½­Þ~initial threadšª¶J|2‡¼@ eðØÿÿÿ­Þ~initial threadšª¶J‡2‡/home/gnn/bin/python2.6­Þ~initial threadšª¶J¡2‡¼­Þ~initial threadšª¶J«2‡¼@ eðØÿÿÿ­Þ~initial threadšª¶Jµ2‡/bin/python2.6­Þ~initial threadšª¶JÃ2‡¼­Þ~initial threadšª¶JÌ2‡¼@ eðØÿÿÿ­Þ~initial threadšª¶JÖ2‡/sbin/python2.6­Þ~initial threadšª¶Jã2‡¼­Þ~initial threadšª¶Jí2‡¼@ eðØÿÿÿ­Þ~initial threadšª¶Jö2‡/usr/bin/python2.6­Þ~initial threadšª¶J3‡¼­Þ~initial threadšª¶J3‡¼@ eðØÿÿÿ­Þ~initial threadšª¶J3‡/usr/sbin/python2.6­Þ~initial threadšª¶J+3‡¼­Þ~initial threadšª¶J43‡¼@ eðØÿÿÿ­Þ~initial threadšª¶J>3‡/usr/X11/bin/python2.6­Þ~initial threadšª¶JM3‡¼­Þ~initial threadšª¶JV3‡¼@ eðØÿÿÿ­Þ~initial threadšª¶J`3‡/usr/local/bin/python2.6}­Þ~initial threadšª¶Ju3‡stat[ÔÈm»šª¶JÕ²Jë²J˜ÿ  Õ²J­Þ~initial threadšª¶J~3‡¼ ­Þ~initial threadšª¶JÍ3‡:@ eðØÿÿÿ­Þ~initial threadšª¶JØ3‡/usr/local/bin/python2.6­Þ~initial threadšª¶Jÿ3‡:º­Þ~initial threadšª¶J 4‡¼˜ePØÿÿÿ­Þ~initial threadšª¶J4‡/usr/local/bin/Modules/Setup­Þ~initial threadšª¶J'4‡¼­Þ~initial threadšª¶J04‡¼˜e@Øÿÿÿ"­Þ~initial threadšª¶J:4‡/usr/local/bin/lib/python2.6/os.py­Þ~initial threadšª¶JK4‡¼­Þ~initial threadšª¶JV4‡¼˜e@Øÿÿÿ#­Þ~initial threadšª¶J`4‡/usr/local/bin/lib/python2.6/os.pyc­Þ~initial threadšª¶Jq4‡¼­Þ~initial threadšª¶Jz4‡¼˜e@Øÿÿÿ­Þ~initial threadšª¶Jƒ4‡/usr/local/lib/python2.6/os.py}­Þ~initial threadšª¶Jœ4‡stat[h%$Xô²JÖ²JÖ²J{f4Ö²J­Þ~initial threadšª¶J¥4‡¼­Þ~initial threadšª¶J¯4‡¼ œePØÿÿÿ­Þ~initial threadšª¶J¸4‡/usr/local/bin/Modules/Setup­Þ~initial threadšª¶JÊ4‡¼­Þ~initial threadšª¶JÓ4‡¼ œePØÿÿÿ(­Þ~initial threadšª¶JÜ4‡/usr/local/bin/lib/python2.6/lib-dynload­Þ~initial threadšª¶Jî4‡¼­Þ~initial threadšª¶J÷4‡¼ œePØÿÿÿ$­Þ~initial threadšª¶J5‡/usr/local/lib/python2.6/lib-dynload}­Þ~initial threadšª¶Jh5‡stat[UÎíATí(ÔµJë²Jë²Jë²J­Þ~initial threadšª¶Jq5‡¼ ­Þ~initial threadšª¶J;‡  àåÿÿÿÀåÿÿÿ­Þ~initial threadšª¶J ;‡  ­Þ~initial threadšª¶J;‡ àåÿÿÿÀåÿÿÿ­Þ~initial threadšª¶J ;‡ ­Þ~initial threadšª¶J/;‡­Þ~initial threadšª¶J8;‡~ ­Þ~initial threadšª¶JO;‡ Àåÿÿÿ­Þ~initial threadšª¶JY;‡  ­Þ~initial threadšª¶Jb;‡ Àåÿÿÿ­Þ~initial threadšª¶Jk;‡  ­Þ~initial threadšª¶Jt;‡ Àåÿÿÿ­Þ~initial threadšª¶J~;‡  ­Þ~initial threadšª¶J‡;‡ Àåÿÿÿ­Þ~initial threadšª¶J;‡  ­Þ~initial threadšª¶J™;‡ Àåÿÿÿ­Þ~initial threadšª¶J¢;‡  ­Þ~initial threadšª¶J«;‡ Àåÿÿÿ­Þ~initial threadšª¶J´;‡  ­Þ~initial threadšª¶J½;‡ Àåÿÿÿ­Þ~initial threadšª¶JÆ;‡  ­Þ~initial threadšª¶JÏ;‡ Àåÿÿÿ­Þ~initial threadšª¶JØ;‡  ­Þ~initial threadšª¶Já;‡  Àåÿÿÿ­Þ~initial threadšª¶J4<‡  ­Þ~initial threadšª¶J=<‡  Àåÿÿÿ­Þ~initial threadšª¶JG<‡  ­Þ~initial threadšª¶JP<‡  Àåÿÿÿ­Þ~initial threadšª¶JY<‡  ­Þ~initial threadšª¶Jb<‡  Àåÿÿÿ­Þ~initial threadšª¶Jk<‡  ­Þ~initial threadšª¶Jt<‡  Àåÿÿÿ­Þ~initial threadšª¶J}<‡  ­Þ~initial threadšª¶J†<‡ Àåÿÿÿ­Þ~initial threadšª¶J<‡  ­Þ~initial threadšª¶J™<‡ Àåÿÿÿ­Þ~initial threadšª¶J¢<‡  ­Þ~initial threadšª¶Jª<‡ Àåÿÿÿ­Þ~initial threadšª¶J³<‡  ­Þ~initial threadšª¶J½<‡ Àåÿÿÿ­Þ~initial threadšª¶JÆ<‡  ­Þ~initial threadšª¶JÏ<‡ Àåÿÿÿ­Þ~initial threadšª¶JØ<‡  ­Þ~initial threadšª¶Já<‡ Àåÿÿÿ­Þ~initial threadšª¶Jê<‡  ­Þ~initial threadšª¶Jó<‡ Àåÿÿÿ­Þ~initial threadšª¶Jü<‡  ­Þ~initial threadšª¶J=‡ Àåÿÿÿ­Þ~initial threadšª¶J=‡  ­Þ~initial threadšª¶Jf=‡ Àåÿÿÿ­Þ~initial threadšª¶Jp=‡  ­Þ~initial threadšª¶Jz=‡ Àåÿÿÿ­Þ~initial threadšª¶Jƒ=‡  ­Þ~initial threadšª¶JŒ=‡ Àåÿÿÿ­Þ~initial threadšª¶J•=‡  ­Þ~initial threadšª¶JŸ=‡ Àåÿÿÿ­Þ~initial threadšª¶J©=‡  ­Þ~initial threadšª¶JÄ=‡ Àåÿÿÿ­Þ~initial threadšª¶JÎ=‡  ­Þ~initial threadšª¶J×=‡ Àåÿÿÿ­Þ~initial threadšª¶Jà=‡  ­Þ~initial threadšª¶Jé=‡ Àåÿÿÿ­Þ~initial threadšª¶Jò=‡  ­Þ~initial threadšª¶Jû=‡ Àåÿÿÿ­Þ~initial threadšª¶J>‡  ­Þ~initial threadšª¶J>‡ Àåÿÿÿ­Þ~initial threadšª¶J>‡  ­Þ~initial threadšª¶J >‡ Àåÿÿÿ­Þ~initial threadšª¶J)>‡  ­Þ~initial threadšª¶J2>‡ °åÿÿÿåÿÿÿ­Þ~initial threadšª¶J<>‡ ­Þ~initial threadšª¶JÁ>‡¼ðÊÿÿÿÏÿÿÿ­Þ~initial threadšª¶JË>‡/usr/local/lib/python26.zip­Þ~initial threadšª¶Já>‡¼­Þ~initial threadšª¶Jõ>‡¼ðÊÿÿÿÏÿÿÿ­Þ~initial threadšª¶JK?‡/usr/local/lib}­Þ~initial threadšª¶J`?‡stat[)¬íA x_ª¶JÓ•µJÓ•µJ0†$²J­Þ~initial threadšª¶Ji?‡¼­Þ~initial threadšª¶J{?‡¼”ËÂ0Ïÿÿÿ­Þ~initial threadšª¶J†?‡/usr/local/lib/python26.zip­Þ~initial threadšª¶J™?‡¼­Þ~initial threadšª¶Jª?‡¼ðÊÿÿÿÏÿÿÿ­Þ~initial threadšª¶J´?‡/usr/local/lib/python2.6/}­Þ~initial threadšª¶JÉ?‡stat[¾$íA˜`bª¶Jë²Jë²J6Ô²J­Þ~initial threadšª¶JÒ?‡¼­Þ~initial threadšª¶JÞ?‡¼ÜËÂ0Ïÿÿÿ­Þ~initial threadšª¶Jè?‡/usr/local/lib/python2.6/}­Þ~initial threadšª¶Jý?‡stat[¾$íA˜`bª¶Jë²Jë²J6Ô²J­Þ~initial threadšª¶J@‡¼­Þ~initial threadšª¶J@‡¼Ûÿÿÿ0Úÿÿÿ­Þ~initial threadšª¶J@‡/usr/local/lib/python2.6/site­Þ~initial threadšª¶J/@‡¼ ­Þ~initial threadšª¶JL@‡Ûÿÿÿ¶ ­Þ~initial threadšª¶JY@‡/usr/local/lib/python2.6/site.so­Þ~initial threadšª¶Jn@‡ ­Þ~initial threadšª¶Jx@‡Ûÿÿÿ¶&­Þ~initial threadšª¶Jƒ@‡/usr/local/lib/python2.6/sitemodule.so­Þ~initial threadšª¶J®@‡ ­Þ~initial threadšª¶J¸@‡Ûÿÿÿ¶ ­Þ~initial threadšª¶JÃ@‡/usr/local/lib/python2.6/site.py­Þ~initial threadšª¶Jê@‡­Þ~initial threadšª¶Jô@‡½ Úÿÿÿ}­Þ~initial threadšª¶Jÿ@‡stat[%$P!ô²JÖ²JÖ²JDH(Ö²J­Þ~initial threadšª¶JA‡½ ­Þ~initial threadšª¶JA‡Öÿÿÿ¶!­Þ~initial threadšª¶JA‡/usr/local/lib/python2.6/site.pyc­Þ~initial threadšª¶J3A‡­Þ~initial threadšª¶JEA‡½€Ôÿÿÿ}­Þ~initial threadšª¶JQA‡stat[*$¸4ª¶Já²Já²J;H(Þ²J­Þ~initial threadšª¶JYA‡½ ­Þ~initial threadšª¶JgA‡Ë­Þ~initial threadšª¶JxA‡Ñò Ö²Jc@sTdZddkZddkZddkZeieigZdada da d„Z d„Z d„Z d„Zd„Zd„Zdd „Zd „Zd „Zd „Zd „Zd„Zdefd„ƒYZd„Zdefd„ƒYZd„Zd„Zd„Zd„Zd„Zd„Z e ƒd„Z!e"djo e!ƒndS(sN Append module search paths for third-party packages to sys.path. **************************************************************** * This module is automatically imported during initialization. * **************************************************************** In earlier versions of Python (up to 1.5a3), scripts or modules that needed to use site-specific modules would place ``import site'' somewhere near the top of their code. Because of the automatic import, this is no longer necessary (but code that does it still works). This will append site-specific paths to the module search path. On Unix (including Mac OSX), it starts with sys.prefix and sys.exec_prefix (if different) and appends lib/python/site-packages as well as lib/site-python. On other platforms (such as Windows), it tries each of the prefixes directly, as well as with lib/site-packages appended. The resulting directories, if they exist, are appended to sys.path, and also inspected for path configuration files. A path configuration file is a file whose name has the form .pth; its contents are additional directories (one per line) to be added to sys.path. Non-existing directories (or non-directories) are never added to sys.path; no directory is added to sys.path more than once. Blank lines and lines beginning with '#' are skipped. Lines starting with 'import' are executed. For example, suppose sys.prefix and sys.exec_prefix are set to /usr/local and there is a directory /usr/local/lib/python2.5/site-packages with three subdirectories, foo, bar and spam, and two path configuration files, foo.pth and bar.pth. Assume foo.pth contains the following: # foo package configuration foo bar bletch and bar.pth contains: # bar package configuration bar Then the following directories are added to sys.path, in this order: /usr/local/lib/python2.5/site-packages/bar /usr/local/lib/python2.5/site-packages/foo Note that bletch is omitted because it doesn't exist; bar precedes foo because bar.pth comes alphabetically before foo.pth; and spam is omitted because it is not mentioned in either path configuration file. After these path manipulations, an attempt is made to import a module named sitecustomize, which can perform arbitrary additional site-specific customizations. If this import fails with an ImportError exception, it is silently ignored. iÿÿÿÿNcGs4tiitii|Œƒ}|tii|ƒfS(N(tostpathtabspathtjointnormcase(tpathstdir((s /usr/local/lib/python2.6/site.pytmakepathKscCsjxctiiƒD]R}t|dƒoqnytii|iƒ|_Wqtj o qqXqWdS(s6Set all module' __file__ attribute to an absolute patht __loader__N( tsystmodulestvaluesthasattrRRRt__file__tAttributeError(tm((s /usr/local/lib/python2.6/site.pyt abs__file__PscCsng}tƒ}xNtiD]C}t|ƒ\}}||jo|i|ƒ|i|ƒqqW|ti(|S(sK Remove duplicate entries from sys.path along with making them absolute(tsetR RRtappendtadd(tLt known_pathsRtdircase((s /usr/local/lib/python2.6/site.pytremoveduppaths[s     cCs€ddkl}d|ƒtif}ttdƒo|d7}ntiitiitidƒ|ƒ}tii |ƒdS(sbAppend ./build/lib. in case we're running in the build dir (especially for Guido :-)iÿÿÿÿ(t get_platformsbu­Þ~initial threadšª¶JßA‡­Þ~initial threadšª¶JöA‡½ •ÿÿÿ}­Þ~initial threadšª¶JB‡stat[*$¸4šª¶Já²Já²J;H(Þ²J­Þ~initial threadšª¶J B‡½ ­Þ~initial threadšª¶JQB‡Ë­Þ~initial threadšª¶JaB‡ild/lib.%s-%.3stgettotalrefcounts-pydebugN( tdistutils.utilRR tversionR RRRtdirnameR(Rts((s /usr/local/lib/python2.6/site.pyt addbuilddiros (cCsttƒ}xdtiD]Y}y:tii|ƒo#t|ƒ\}}|i|ƒnWqtj o qqXqW|S(sDReturn a set containing all existing directory entries from sys.path(RR RRtisdirRRt TypeError(tdRR((s /usr/local/lib/python2.6/site.pyt_init_pathinfozs   c Bs9|djoeƒd}nd}eii||ƒ}ye|dƒ}Wnej odSX|iiƒz­x¦|D]ž}|i dƒoq|n|i dƒo|dUq|n|i ƒ}e ||ƒ\}}||jo4eii |ƒo!e ii|ƒ|i|ƒq|q|WWdQX|o d}n|S( sÖProcess a .pth file within the site-packages directory: For each line in the file, either combine it with sitedir to a path and add that to known_paths, or execute it if it starts with 'import '. iitrUNt#simport simport (simport simport (tNoneR"RRRtopentIOErrort__exit__t __enter__t startswithtrstripRtexistsR RR( tsitedirtnameRtresettfullnametftlineRR((s /usr/local/lib/python2.6/site.pyt addpackage‡s2     c Cs|djotƒ}d}nd}t|ƒ\}}||jotii|ƒnyti|ƒ}Wntij odSXti d}g}|D]!}|i |ƒo ||qžqž~}x$t |ƒD]}t |||ƒqÕW|o d}n|S(sTAdd 'sitedir' argument to sys.path if missing and handle .pth files in 'sitedir'iiNtpth( R%R"RR RRRtlistdirterrortextseptendswithtsortedR3(R-RR/t sitedircasetnamestdotptht_[1]R.((s /usr/local/lib/python2.6/site.pyt addsitedir§s&     5  cCsštiiotSttdƒo2ttdƒo"tiƒtiƒjodSnttdƒo2ttdƒo"ti ƒti ƒjodSnt S(s,Check if user site directory is safe for inclusion The function tests for the command line flag (including environment var), process uid/gid equal to effective uid/gid. None: Disabled for security reasons False: Disabled by user (command line option) True: Safe and enabled tgetuidtgeteuidtgetgidtgetegidN( R tflagst no_user_sitetFalseR RR@R?R%RBRAtTrue(((s /usr/local/lib/python2.6/site.pytcheck_enableusersite¿s     cCstiiddƒ}d„}tidjohtiidƒpd}|o|n ||dƒatiitdti dti dd ƒa nD|o|n |dd ƒatiitd d ti d d ƒa t o$tii t ƒot t |ƒn|S(s'Add a per user site-package to sys.path Each user has its own python directory with site-packages in the home directory. USER_BASE is the root directory for all Python versions USER_SITE is the user specific site-packages directory USER_SITE/.. can be used for data. tPYTHONUSERBASEcWstiitii|ŒƒS(N(RRt expanduserR(targs((s /usr/local/lib/python2.6/site.pytjoinuserçstnttAPPDATAt~tPythoniis site-packagess.localtlibtpythoniN(RtenvirontgetR%R.t USER_BASERRR Rt USER_SITEtENABLE_USER_SITERR>(Rtenv_baseRKtbase((s /usr/local/lib/python2.6/site.pyt­Þ~initial threadšª¶J±B‡ ­Þ~initial threadšª¶JC‡Ë­Þ~initial threadšª¶JC‡addusersitepackagesØs     c Cs›g}g}xStD]K}| p ||joqn|i|ƒtidjo#|itii|ddƒƒntidjoP|itii|ddtid dƒƒ|itii|dd ƒƒn-|i|ƒ|itii|ddƒƒtid joMd |jo<|itii tiid d dtid dƒƒƒq^qqWx2|D]*}tii |ƒot ||ƒqiqiW|S(s8Add site-packages (and possibly site-python) to sys.pathtos2emxtriscostLibs site-packagest/RPRQis site-pythontdarwinsPython.frameworkRNtLibraryRO(sos2emxsriscos( tPREFIXESRR tplatformRRRtsepRRIRR>(RtsitedirstseentprefixR-((s /usr/local/lib/python2.6/site.pytaddsitepackagesÿs6 # #   #cCsqtiitiddƒ}tididƒ}|do|i|ƒn ||deZdZdZddd„Zd„Zd„Zd„ZRS(sninteractive prompt objects for printing the license text, a list of contributors and the copyright notice.icCs1||_||_||_||_d|_dS(N(t_Printer__namet_Printer__datat_Printer__filest_Printer__dirsR%t_Printer__lines(RoR.tdatatfilestdirs((s /usr/local/lib/python2.6/site.pyRpYs     cCsÚ|iodSd}x†|iD]{}xf|iD][}tii||ƒ}y*t|dƒ}|iƒ}|i ƒPWq/t j oq/Xq/W|oPqqW|p |i }n|i dƒ|_t |iƒ|_dS(NR#s (R„R%RƒR‚RRRtfiletreadRtR'RRitlent_Printer__linecnt(RoR…Rtfilenametfp((s /usr/local/lib/python2.6/site.pyt__setup`s*        cCsJ|iƒt|iƒ|ijodi|iƒSd|ifdSdS(Ns s!Type %s() to see the full %s texti­Þ~initial threadšª¶JnC‡ ­Þ~initial threadšª¶JxC‡Ë­Þ~initial threadšª¶J‡C‡(t_Printer__setupRŠR„tMAXLINESRR€(Ro((s /usr/local/lib/python2.6/site.pyRrus cCsÅ|iƒd}d}x¨y1x*t|||iƒD]}|i|GHq3WWntj oPqX||i7}d}x5|djo't|ƒ}|djo d}qwqwW|djoPqqdS(Ns0Hit Return for more, or q (and Return) to quit: ittq(R‘R’(RtrangeRR„t IndexErrorR%t raw_input(Rotprompttlinenotitkey((s /usr/local/lib/python2.6/site.pyRw|s&      (((RxRyt__doc__RRpRRrRw(((s /usr/local/lib/python2.6/site.pyRSs   cCs­tdtiƒt_tid djotddƒt_ntddƒt_tiiti ƒ}tddti d d gtii |ti ƒ|ti gƒt_d S( s,Set 'copyright' and 'credits' in __builtin__t copyrightitjavatcreditss?Jython is maintained by the Jython developers (www.jython.org).sž Thanks to CWI, CNRI, BeOpen.com, Zope Corporation and a cast of thousands for supporting Python development. See www.python.org for more information.tlicenses+See http://www.python.org/%.3s/license.htmls LICENSE.txttLICENSEN(RR R›R}RaRRRRR RRtpardirtcurdirRž(there((s /usr/local/lib/python2.6/site.pyt setcopyrights   t_HelpercBs eZdZd„Zd„ZRS(sYDefine the built-in 'help'. This is a wrapper around pydoc.help (with a twist). cCsdS(NsHType help() for interactive help, or help(object) for help about object.((Ro((s /usr/local/lib/python2.6/site.pyRr¨scOsddk}|i||ŽS(Niÿÿÿÿ(tpydocthelp(RoRJtkwdsR¥((s /usr/local/lib/python2.6/site.pyRw«s (RxRyRšRrRw(((s /usr/local/lib/python2.6/site.pyR¤¢s cCstƒt_dS(N(R¤R}R¦(((s /usr/local/lib/python2.6/site.pyt sethelper¯scCs§tidjo“ddk}ddk}|iƒd}|idƒoWy|i|ƒWqŸtj o3ddk}|i |i |2 - unknown error is sys.path = [s %r,t]sUSER_BASE: %r (%s)R,s doesn't existsUSER_SITE: %r (%s)sENABLE_USER_SITE: %ris --user-bases --user-siteiiiÿÿÿÿi (R targvRRTRRRURVR{RtpathsepRRER%ttextwraptdedent(R¦RJRtbufferRÇ((s /usr/local/lib/python2.6/site.pyt_scripts>  ##      "t__main__(#RšR RR}Ret exec_prefixR`R%RVRURTRRRRR"R3R>RGRYRfRlR~R|RR£R¤R¨R¶RºR½R¿RÃRÊRx(((s /usr/local/lib/python2.6/site.pyt;s@        ' &  =        1 ­Þ~initial threadšª¶J*D‡; ­Þ~initial threadšª¶J4D‡Ë­Þ~initial threadšª¶J?D‡­Þ~initial threadšª¶JHD‡­Þ~initial threadšª¶JòD‡­Þ~initial threadšª¶J E‡­Þ~initial threadšª¶J6E‡¼0ÈÿÿÿPÇÿÿÿ­Þ~initial threadšª¶JAE‡/usr/local/lib/python2.6/os­Þ~initial threadšª¶JVE‡¼ ­Þ~initial threadšª¶JaE‡0Èÿÿÿ¶­Þ~initial threadšª¶JlE‡/usr/local/lib/python2.6/os.so­Þ~initial threadšª¶JE‡ ­Þ~initial threadšª¶J‹E‡0Èÿÿÿ¶$­Þ~initial threadšª¶J•E‡/usr/local/lib/python2.6/osmodule.so­Þ~initial threadšª¶JªE‡ ­Þ~initial threadšª¶J´E‡0Èÿÿÿ¶­Þ~initial threadšª¶J¾E‡/usr/local/lib/python2.6/os.py­Þ~initial threadšª¶JÔE‡­Þ~initial threadšª¶J"F‡½@Çÿÿÿ}­Þ~initial threadšª¶J.F‡stat[h%$Xô²JÖ²JÖ²J{f4Ö²J­Þ~initial threadšª¶J7F‡½ ­Þ~initial threadšª¶JAF‡0Ãÿÿÿ¶­Þ~initial threadšª¶JKF‡/usr/local/lib/python2.6/os.pyc­Þ~initial threadšª¶JcF‡­Þ~initial threadšª¶JmF‡½ Áÿÿÿ}­Þ~initial threadšª¶JwF‡stat[*$`4ª¶Já²Já²J³g4Þ²J­Þ~initial threadšª¶J€F‡½ ­Þ~initial threadšª¶JŠF‡Ë­Þ~initial threadšª¶JšF‡Ñò Ö²Jc@sHdZddkZddkZeiZddddddd d d d d dddgZd„ZdejordZdZddk Tyddk l Z Wne j onXddk Z ddk Z eiee ƒƒ[ n?dejordZdZddkTyddkl Z Wne j onXddkZ ddkZeieeƒƒ[nÀdejo«dZdZddkTyddkl Z Wne j onXeiidƒdjoddkZ nddkZ ddklZddkZeieeƒƒ[ndejordZdZddkTyddkl Z Wne j onXddkZ ddkZeieeƒƒ[n‰dejordZdZddkTyddkl Z Wne j onXddkZ ddkZeieeƒƒ[n e d‚e eid„Z>ei.d?ƒd@„Z?e?dAƒo\e?dBƒ oNe?dCƒoAd Z@d!ZAZBdD„ZCdE„ZDdF„ZEdG„ZFdH„ZGne?dBƒo/dI„ZHdJ„ZIeidBdKdLdMgƒne?dNƒo/dO„ZJdP„ZKeidNdQdRdSgƒne?dAƒo‹e?dTƒp dUddV„ZLei.dTƒne?dWƒp dUddX„ZMei.dWƒne?dYƒp dUddZ„ZNei.dYƒq nddkOZPd[„ZQd\„ZRyePiSeTeReQƒWne0j onXd]„ZUd^„ZVyePiSeWeVeUƒWne0j onXe?d_ƒp d`„ZXndS(csƒOS routines for Mac, NT, or Posix depending on what system we're on. This exports: - all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc. - os.path is one of the modules posixpath, or ntpath - os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos' - os.curdir is a string representing the current directory ('.' or ':') - os.pardir is a string representing the parent directory ('..' or '::') - os.sep is the (or a most common) pathname separator ('/' or ':' or '\\') - os.extsep is the extension separator ('.' or '/') - os.altsep is the alternate pathname separator (None or '/') - os.pathsep is the component separator used in $PATH etc - os.linesep is the line separator in text files ('\r' or '\n' or '\r\n') - os.defpath is the default search path for executables - os.devnull is the file path of the null device ('/dev/null', etc.) Programs that import and use 'os' stand a better chance of being portable between different platforms. Of course, they must then only use functions that are defined by all platforms (e.g., unlink and opendir), and leave all pathname manipulation to os.path (e.g., split and join). iÿÿÿÿNtaltseptcurdirtpardirtseptextseptpathseptlineseptdefpathtnametpathtdevnulltSEEK_SETtSEEK_CURtSEEK_ENDcCsbyt|iƒSWnJtj o>g}t|ƒD]"}|ddjo ||q3q3~SXdS(Nit_(tlistt__all__tAttributeErrortdir(tmodulet_[1]tn((s/usr/local/lib/python2.6/os.pyt_get_exports_list#stposixs (t*(t_exittnts tos2sEMX GCC(tlinktcetriscossno os specific module foundsos.path(RRRRRRRR iiiiÿcCs¾ti|ƒ\}}|pti|ƒ\}}n|oq|ojti|ƒ oYyt||ƒWn/tj o#}|itijo‚q—nX|tjodSnt||ƒdS(smakedirs(path [, mode=0777]) Super-mkdir; create a leaf directory and all intermediate ones. Works like mkdir, except tha­Þ~initial threadšª¶JïF‡­Þ~initial threadšª¶JùF‡½À‚ÿÿÿ}­Þ~initial threadšª¶JG‡stat[*$`4šª¶Já²Já²J³g4Þ²J­Þ~initial threadšª¶J G‡½ ­Þ~initial threadšª¶J]G‡Ë­Þ~initial threadšª¶JmG‡t any intermediate path segment (not just the rightmost) will be created if it does not exist. This is recursive. N( R tsplittexiststmakedirstOSErrorterrnotEEXISTRtmkdir(Rtmodetheadttailte((s/usr/local/lib/python2.6/os.pyR!ˆs    cCs“t|ƒti|ƒ\}}|pti|ƒ\}}nxM|oE|o>yt|ƒWntj oPnXti|ƒ\}}qBWdS(s¬removedirs(path) Super-rmdir; remove a leaf directory and all empty intermediate ones. Works like rmdir except that, if the leaf directory is successfully removed, directories corresponding to rightmost path segments will be pruned away until either the whole path is consumed or an error occurs. Errors during this latter phase are ignored -- they generally mean that a directory was not empty. N(trmdirR Rterror(RR'R(((s/usr/local/lib/python2.6/os.pyt removedirsŸs cCsžti|ƒ\}}|o&|oti|ƒ ot|ƒnt||ƒti|ƒ\}}|o/|o(yt|ƒWqštj oqšXndS(s@renames(old, new) Super-rename; create directories as necessary and delete any left empty. Works like rename, except creation of any intermediate directories needed to make the new pathname good is attempted first. After the rename, directories corresponding to rightmost path segments of the old name will be pruned way until either the whole path is consumed or a nonempty directory is found. Note: this function can fail with the new directory structure made if you lack permissions needed to unlink the leaf directory or file. N(R RR R!trenameR,R+(toldtnewR'R(((s/usr/local/lib/python2.6/os.pytrenamesµs R!R,R0c csFddkl}l}l}yt|ƒ}Wn1tj o%}|dj o||ƒndSXgg} } xB|D]:} |||| ƒƒo| i| ƒqt| i| ƒqtW|o|| | fVnx[| D]S} ||| ƒ} |p|| ƒ o)x&t| |||ƒD] } | VqWqÒqÒW|p|| | fVndS(s< Directory tree generator. For each directory in the directory tree rooted at top (including top itself, but excluding '.' and '..'), yields a 3-tuple dirpath, dirnames, filenames dirpath is a string, the path to the directory. dirnames is a list of the names of the subdirectories in dirpath (excluding '.' and '..'). filenames is a list of the names of the non-directory files in dirpath. Note that the names in the lists are just names, with no path components. To get a full path (which begins with top) to a file or directory in dirpath, do os.path.join(dirpath, name). If optional arg 'topdown' is true or not specified, the triple for a directory is generated before the triples for any of its subdirectories (directories are generated top down). If topdown is false, the triple for a directory is generated after the triples for all of its subdirectories (directories are generated bottom up). When topdown is true, the caller can modify the dirnames list in-place (e.g., via del or slice assignment), and walk will only recurse into the subdirectories whose names remain in dirnames; this can be used to prune the search, or to impose a specific order of visiting. Modifying dirnames when topdown is false is ineffective, since the directories in dirnames have already been generated by the time dirnames itself is generated. By default errors from the os.listdir() call are ignored. If optional arg 'onerror' is specified, it should be a function; it will be called with one argument, an os.error instance. It can report the error to continue with the walk, or raise t­Þ~initial threadšª¶J¾G‡ ­Þ~initial threadšª¶JÉG‡Ë­Þ~initial threadšª¶JØG‡he exception to abort the walk. Note that the filename is available as the filename attribute of the exception object. By default, os.walk does not follow symbolic links to subdirectories on systems that support them. In order to get this functionality, set the optional argument 'followlinks' to true. Caution: if you pass a relative pathname for top, don't change the current working directory between resumptions of walk. walk never changes the current directory, and assumes that the client doesn't either. Example: import os from os.path import join, getsize for root, dirs, files in os.walk('python/Lib/email'): print root, "consumes", print sum([getsize(join(root, name)) for name in files]), print "bytes in", len(files), "non-directory files" if 'CVS' in dirs: dirs.remove('CVS') # don't visit CVS directories iÿÿÿÿ(tjointisdirtislinkN( tos.pathR1R2R3tlistdirR+tNonetappendtwalk(ttopttopdowntonerrort followlinksR1R2R3tnamesterrtdirstnondirsRR tx((s/usr/local/lib/python2.6/os.pyR8Ñs09  R8cGst||ƒdS(spexecl(file, *args) Execute the executable file with argument list args, replacing the current process. N(texecv(tfiletargs((s/usr/local/lib/python2.6/os.pytexecl3scGs"|d}t||d |ƒdS(sŠexecle(file, *args, env) Execute the executable file with argument list args and environment env, replacing the current process. iÿÿÿÿN(texecve(RCRDtenv((s/usr/local/lib/python2.6/os.pytexecle:s cGst||ƒdS(s•execlp(file, *args) Execute the executable file (which is searched for along $PATH) with argument list args, replacing the current process. N(texecvp(RCRD((s/usr/local/lib/python2.6/os.pytexeclpBscGs"|d}t||d |ƒdS(s³execlpe(file, *args, env) Execute the executable file (which is searched for along $PATH) with argument list args and environment env, replacing the current process. iÿÿÿÿN(texecvpe(RCRDRG((s/usr/local/lib/python2.6/os.pytexeclpeIs cCst||ƒdS(s¿execp(file, args) Execute the executable file (which is searched for along $PATH) with argument list args, replacing the current process. args may be a list or tuple of strings. N(t_execvpe(RCRD((s/usr/local/lib/python2.6/os.pyRIRscCst|||ƒdS(sßexecvpe(file, args, env) Execute the executable file (which is searched for along $PATH) with argument list args and environment env , replacing the current process. args may be a list or tuple of strings. N(RM(RCRDRG((s/usr/local/lib/python2.6/os.pyRKZsRERHRJRLRIRKcCsh|dj ot}||f}nt}|f}t}ti|ƒ\}}|o|||ŒdSd|jo|d}nt}|itƒ}d} d} xœ|D]”} ti| |ƒ} y|| |ŒWq©t j o\} t i ƒd}| i t i jo0| i t ijo| djo| } |} q=q©Xq©W| ot | | ‚nt | |‚dS(NtPATHi(R6RFRBtenvironR RRRR1R+tsystexc_infoR#tENOENTtENOTDIR(RCRDRGtfunctargrestR'R(tenvpathRNt saved_exctsaved_tbRtfullnameR)ttb((s/usr/local/lib/python2.6/os.pyRMes<    & cCst|dƒdS(Nt(tputenv(tkey((­Þ~initial threadšª¶J÷G‡ ­Þ~initial threadšª¶JH‡Ë­Þ~initial threadšª¶JH‡s/usr/local/lib/python2.6/os.pytunsetenv•s(t_EnvironR_cBs˜eZd„Zd„Zd„ZyeWnej od„ZnXd„Zd„Zd„Z d„Z d„Z d d „Z d d „Zd „ZRS( cCsJtii|ƒ|i}x*|iƒD]\}}|||iƒ integer Execute file with arguments from args in a subprocess. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. N(RŒR6RB(R&RCRD((s/usr/local/lib/python2.6/os.pyR0scCst||||tƒS(s:spawnve(mode, file, args, env) -> integer Execute file with arguments from args in a subprocess with the specified environment. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. (RŒRF(R&RCRDRG((s/usr/local/lib/python2.6/os.pytspawnve9scCst|||dtƒS(s8spawnvp(mode, file, args) -> integer Execute file (which is looked for along $PATH) with arguments from args in a subprocess. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. N(RŒR6RI(R&RCRD((s/usr/local/lib/python2.6/os.pytspawnvpEscCst||||tƒS(s\spawnvpe(mode, file, args, env) -> integer Execute file (which is looked for along $PATH) with arguments from args in a subprocess with the supplied environment. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. (RŒRK(R&RCRDRG((s/usr/local/lib/python2.6/os.pytspawnvpeOscGst|||ƒS(sspawnl(mode, file, *args) -> integer Execute file with arguments from args in a subprocess. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. (R(R&RCRD((s/usr/local/lib/python2.6/os.pytspawnl]scGs!|d}t|||d |ƒS(s:spawnle(mode, file, *args, env) -> integer Execute file with arguments from args in a subprocess with the supplied environment. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. iÿÿÿÿ(R(R&RCRDRG((s/usr/local/lib/python2.6/os.pytspawnlefs RRR‘RŽcGst|||ƒS(sWspawnlp(mode, file, *args) -> integer Execute file (which is looked for along $PATH)­Þ~initial threadšª¶JåH‡ ­Þ~initial threadšª¶JðH‡Ë­Þ~initial threadšª¶JI‡ with arguments from args in a subprocess with the supplied environment. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. (RŽ(R&RCRD((s/usr/local/lib/python2.6/os.pytspawnlpxscGs!|d}t|||d |ƒS(s]spawnlpe(mode, file, *args, env) -> integer Execute file (which is looked for along $PATH) with arguments from args in a subprocess with the supplied environment. If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; otherwise return -SIG, where SIG is the signal that killed it. iÿÿÿÿ(R(R&RCRDRG((s/usr/local/lib/python2.6/os.pytspawnlpe‚s RR’R“tpopen2ttcCszddk}d}|i|tddƒddk}|i}|i|dtd|d|d |d tƒ}|i|ifS( sÏExecute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may be a sequence, in which case arguments will be passed directly to the program without shell intervention (as with os.spawnv()). If 'cmd' is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout) are returned.iÿÿÿÿNs4os.popen2 is deprecated. Use the subprocess module.t stacklevelitshelltbufsizetstdintstdoutt close_fds( twarningstwarntDeprecationWarningt subprocesstPIPEtPopenR}R™Rš(tcmdR&R˜RœtmsgRŸR tp((s/usr/local/lib/python2.6/os.pyR””s   tpopen3cCs†ddk}d}|i|tddƒddk}|i}|i|dtd|d|d |d |d tƒ}|i|i|i fS( sÝExecute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may be a sequence, in which case arguments will be passed directly to the program without shell intervention (as with os.spawnv()). If 'cmd' is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout, child_stderr) are returned.iÿÿÿÿNs4os.popen3 is deprecated. Use the subprocess module.R–iR—R˜R™RštstderrR›( RœRRžRŸR R¡R}R™RšR¦(R¢R&R˜RœR£RŸR R¤((s/usr/local/lib/python2.6/os.pyR¥§s    tpopen4cCsƒddk}d}|i|tddƒddk}|i}|i|dtd|d|d |d |id tƒ}|i|i fS( sÖExecute the shell command 'cmd' in a sub-process. On UNIX, 'cmd' may be a sequence, in which case arguments will be passed directly to the program without shell intervention (as with os.spawnv()). If 'cmd' is a string it will be passed to the shell (as with os.system()). If 'bufsize' is specified, it sets the buffer size for the I/O pipes. The file objects (child_stdin, child_stdout_stderr) are returned.iÿÿÿÿNs4os.popen4 is deprecated. Use the subprocess module.R–iR—R˜R™RšR¦R›( RœRRžRŸR R¡R}tSTDOUTR™Rš(R¢R&R˜RœR£RŸR R¤((s/usr/local/lib/python2.6/os.pyR§»s    cCs t||ƒS(N(t stat_result(ttupRt((s/usr/local/lib/python2.6/os.pyt_make_stat_resultÐscCs|iƒ\}}t|fS(N(t __reduce__R«(tsrttypeRD((s/usr/local/lib/python2.6/os.pyt_pickle_stat_re­Þ~initial threadšª¶JvI‡ ­Þ~initial threadšª¶JI‡Ë»­Þ~initial threadšª¶J–I‡sultÓscCs t||ƒS(N(tstatvfs_result(RªRt((s/usr/local/lib/python2.6/os.pyt_make_statvfs_resultÜscCs|iƒ\}}t|fS(N(R¬R±(R­R®RD((s/usr/local/lib/python2.6/os.pyt_pickle_statvfs_resultßsturandomc Cs“ytdtƒ}Wn%ttfj otdƒ‚nXzFd}x9|t|ƒdjo!|t||t|ƒƒ7}qGWWdt|ƒX|S(sfurandom(n) -> str Return a string of n random bytes suitable for cryptographic use. s /dev/urandoms&/dev/urandom (or equivalent) not foundR[iN(topentO_RDONLYR"tIOErrortNotImplementedErrortlentreadtclose(Rt _urandomfdtbs((s/usr/local/lib/python2.6/os.pyR³ês& (sos2snt(sos2snt(Yt__doc__RPR#tbuiltin_module_namest_namesRRRRRRt ImportErrort posixpathR textendRtntpathRtversiontfindt os2emxpatht _emx_linkRRRt riscospathtmodulesR4RRRRRRRR R R R R!R,R0R}R6R~R8R7RORyRERHRJRLRIRKRMR\R`R^t riscosenvironR_tIterableUserDictR{RtP_WAITR‚t P_NOWAITORŒRRRŽRRR‘R’R“R”R¥R§tcopy_regt _copy_regR«R¯tpickleR©R±R²R°R³(((s/usr/local/lib/python2.6/os.pyts0                         :   Z        #     5*    (                  ­Þ~initial threadšª¶JåI‡³ ­Þ~initial threadšª¶JïI‡Ë­Þ~initial threadšª¶JúI‡­Þ~initial threadšª¶JJ‡8­Þ~initial threadšª¶JµJ‡Ýÿÿÿÿ­Þ~initial threadšª¶JÎJ‡ÝЭÞ~initial threadšª¶J.M‡­Þ~initial threadšª¶J?M‡­Þ~initial threadšª¶JÂO‡¼Pµÿÿÿp´ÿÿÿ"­Þ~initial threadšª¶JÎO‡/usr/local/lib/python2.6/posixpath­Þ~initial threadšª¶JäO‡¼ ­Þ~initial threadšª¶JïO‡Pµÿÿÿ¶%­Þ~initial threadšª¶JúO‡/usr/local/lib/python2.6/posixpath.so­Þ~initial threadšª¶JP‡ ­Þ~initial threadšª¶JP‡Pµÿÿÿ¶+­Þ~initial threadšª¶J#P‡/usr/local/lib/python2.6/posixpathmodule.so­Þ~initial threadšª¶J8P‡ ­Þ~initial threadšª¶JBP‡Pµÿÿÿ¶%­Þ~initial threadšª¶JšP‡/usr/local/lib/python2.6/posixpath.py­Þ~initial threadšª¶J²P‡­Þ~initial threadšª¶JÅP‡½`´ÿÿÿ}­Þ~initial threadšª¶JÑP‡stat[t%$Ðô²JÖ²JÖ²JÞ1Ö²J­Þ~initial threadšª¶JÚP‡½ ­Þ~initial threadšª¶JãP‡P°ÿÿÿ¶&­Þ~initial threadšª¶JîP‡/usr/local/lib/python2.6/posixpath.pyc­Þ~initial threadšª¶JQ‡­Þ~initial threadšª¶JQ‡½À®ÿÿÿ}­Þ~initial threadšª¶JQ‡stat[‘*$(Cª¶Já²Já²J+Þ²J­Þ~initial threadšª¶J"Q‡½ ­Þ~initial threadšª¶J-Q‡Í­Þ~initial threadšª¶J2Q‡Ñò Ö²Jc+@sÐdZddkZddkZddkZddkZddkTdddddd d d d d ddddddddddddddddddd d!d"d#d$d%d&d'd(d)g&Zd*Zd+Zd*Zd,Z d-Z d.Z dZ d/Zd0„Zd1„Zd2„Zd3„Zd4„Zeiie_d5„Zd6„Zd7„Zd8„Zd9„Zd:„Zd;„Zd<„Zd=„Zd>„Zd?„Zda d@„Z!dA„Z"dB„Z#dC„Z$dD„Z%e&Z'edE„Z(dS(FsçCommon operations on Posix pathnames. Instead of importing this module directly, import os and refer to this module as os.path. The "os.path" name is an alias for this module on Posix systems; on other systems (e.g. Mac, Windows), os.path provides the same operations in a manner specific to that platform, and is an alias to another module (e.g. macpath, ntpath). Some of this can actually be useful on non-Posix systems too, e.g. for manipulation of the pathname component of URLs. iÿÿÿÿN(t*tnormcasetisabstjoint splitdrivetsplittsplitexttbasenametdirnamet commonprefixtgetsizetgetmtimetgetatimetgetctimetislinktexiststlexiststisdirtisfiletismounttwalkt expandusert expandvarstnormpathtabspathtsamefilet sameopenfiletsamestattcurdirtpardirtseptpathseptdefpathtaltseptextseptdevnulltrealpathtsupports_unicode_filenamestrelpatht.s..t/t:s:/bin:/usr/bins /dev/nullcCs|S(s6Normalize case of pathname. Has no effect under Posix((ts((s%/usr/local/lib/python2.6/posixpath.pyR*scCs |idƒS(sTest whether a path is absoluteR((t startswith(R*((s%/usr/local/lib/python2.6/posixpath.pyR2scGsn|}xa|D]Y}|idƒo |}q |djp|idƒo||7}q |d|7}q W|S(sœJoin two or more pathname components, inserting '/' as needed. If any component is an absolute path, all previous path components will be discarded.R(t(R+tendswith(tatptpathtb((s%/usr/local/lib/python2.6/posixpath.pyR;s cCsc|idƒd}|| ||}}|o*|dt|ƒjo|idƒ}n||fS(s€Split a pathname. Returns tuple "(head, tail)" where "tail" is everything after the final slash. Either part may be empty.R(i(trfindtlentrstrip(R/titheadttail((s%/usr/local/lib/python2.6/posixpath.pyROs cCsti|tttƒS(N(t genericpatht _splitextRR!R"(R/((s%/usr/local/lib/python2.6/posixpath.pyR^scCs d|fS(sJSplit a pathname into drive and path. On Posix, drive is always empty.R,((R/((s%/usr/local/lib/python2.6/posixpath.pyRescCs|idƒd}||S(s)Returns the final component of a pathnameR(i(R2(R/R5((s%/usr/local/lib/python2.6/posixpath.pyRmscCsR|idƒd}|| }|o*|dt|ƒjo|idƒ}n|S(s-Returns the directory component of a pathnameR(i(R2R3R4(R/R5R6((s%/usr/local/lib/python2.6/posixpath.pyRus  cCsCyti|ƒ}Wntitfj otSXti|iƒS(s&Test whether a path is a symbolic link(tostlstatterrortAttributeErrortFalsetstattS_ISLNKtst_mode(R0tst((s%/usr/local/lib/python2.6/posixpath.pyRs cCs1yti|ƒ}Wntij otSXtS(sCTest whether a path exists. Returns True for broken symbol­Þ~initial threadšª¶J–Q‡­Þ~initial threadšª¶J¬Q‡½àoÿÿÿ}­Þ~initial threadšª¶J·Q‡stat[‘*$(Cšª¶Já²Já²J+Þ²J­Þ~initial threadšª¶JÀQ‡½ ­Þ~initial threadšª¶JÊQ‡Í­Þ~initial threadšª¶JÚQ‡ic links(R:R;R<R>tTrue(R0RB((s%/usr/local/lib/python2.6/posixpath.pyR‹s cCs+ti|ƒ}ti|ƒ}t||ƒS(s9Test whether two pathnames reference the same actual file(R:R?R(tf1tf2ts1ts2((s%/usr/local/lib/python2.6/posixpath.pyR–scCs+ti|ƒ}ti|ƒ}t||ƒS(s:Test whether two open file objects reference the same file(R:tfstatR(tfp1tfp2RFRG((s%/usr/local/lib/python2.6/posixpath.pyR scCs#|i|ijo|i|ijS(s5Test whether two stat buffers reference the same file(tst_inotst_dev(RFRG((s%/usr/local/lib/python2.6/posixpath.pyRªscCs‘y+ti|ƒ}tit|dƒƒ}Wntij otSX|i}|i}||jotS|i}|i}||jotStS(s$Test whether a path is a mount points..(R:R;RR<R>RLRCRK(R0RFRGtdev1tdev2tino1tino2((s%/usr/local/lib/python2.6/posixpath.pyR³s      c CsÄtidƒyti|ƒ}Wntij odSX||||ƒxs|D]k}t||ƒ}yti|ƒ}Wntij o qQnXti|i ƒot |||ƒqQqQWdS(sIDirectory tree walk with callback function. For each directory in the directory tree rooted at top (including top itself, but excluding '.' and '..'), call func(arg, dirname, fnames). dirname is the name of the directory, and fnames a list of the names of the files and subdirectories in dirname (excluding '.' and '..'). func may modify the fnames list in-place (e.g. via del or slice assignment), and walk will only recurse into the subdirectories whose names remain in fnames; this can be used to implement a filter, or to impose a specific order of visiting. No semantics are defined for, or required of, arg, beyond that arg is always passed to func. It can be used, e.g., to pass a filename pattern, or a mutable object designed to accumulate statistics. Passing None for arg is common.s4In 3.x, os.path.walk is removed in favor of os.walk.N( twarningstwarnpy3kR:tlistdirR<RR;R?tS_ISDIRRAR(ttoptfunctargtnamestnameRB((s%/usr/local/lib/python2.6/posixpath.pyRÍs cCs|idƒp|S|iddƒ}|djot|ƒ}n|djoIdtijo(ddk}|itiƒƒi}qàtid}nGddk}y|i |d|!ƒ}Wnt j o|SX|i}|i dƒp|}|||S(sOExpand ~ and ~user constructions. If user or $HOME is unknown, do nothing.t~R(iitHOMEiÿÿÿÿN( R+tfindR3R:tenvirontpwdtgetpwuidtgetuidtpw_dirtgetpwnamtKeyErrorR4(R0R5R^tuserhometpwent((s%/usr/local/lib/python2.6/posixpath.pyRôs$     cCsd|jo|Stpddk}|idƒand}xÎtoÆti||ƒ}|pPn|idƒ\}}|idƒ}|idƒo!|idƒo|dd!}n|t i jo9||}|| t i |}t |ƒ}||7}qA|}qAW|S( sZExpand shell variables of form $var and ${var}. Unknown variables are left unchanged.t$iÿÿÿÿNs\$(\w+|\{[^}]*\})iit{t}( t_varprogtretcompileRCtsearchtspantgroupR+R-R:R]R3(R0RjR5tmtjRYR7((s%/usr/local/lib/python2.6/posixpath.pyRs,      cCs!|djodS|idƒ}|o+|­Þ~initial threadšª¶J3R‡ ­Þ~initial threadšª¶J=R‡Í ­Þ~initial threadšª¶JMR‡idƒo|idƒ o d}n|idƒ}g}x}|D]u}|d joqon|djp(| o| p|o"|ddjo|i|ƒqo|o|iƒqoqoW|}di|ƒ}|od||}n|pdS( s0Normalize path, eliminating double slashes, etc.R,R'R(s//s///is..iÿÿÿÿ(R,R'(R+RtappendtpopR(R0tinitial_slashestcompst new_compstcomp((s%/usr/local/lib/python2.6/posixpath.pyR3s, !  cCs0t|ƒpttiƒ|ƒ}nt|ƒS(sReturn an absolute path.(RRR:tgetcwdR(R0((s%/usr/local/lib/python2.6/posixpath.pyRNs cCsét|ƒodg|idƒd}ndg|idƒ}x›tdt|ƒdƒD]€}t|d|!Œ}t|ƒoZt|ƒ}|djott|g||ŒƒSt|g||Œ}t |ƒSq[q[Wt|ƒS(slReturn the canonical path of the specified filename, eliminating any symbolic links encountered in the path.R(iR,iiN( RRtrangeR3RRt _resolve_linktNoneRR$(tfilenametbitsR5t componenttresolvedtnewpath((s%/usr/local/lib/python2.6/posixpath.pyR$Xs    cCs‹g}x~t|ƒop||jodS|i|ƒti|ƒ}t|ƒp%t|ƒ}tt||ƒƒ}q t|ƒ}q W|S(sÈInternal helper function. Takes a path and follows symlinks until we either arrive at something that isn't a symlink, or encounter a path we've seen before (meaning that there's a loop). N( RRzRqR:treadlinkRRRR(R0t paths_seenR~tdir((s%/usr/local/lib/python2.6/posixpath.pyRyos     cCsŽ|ptdƒ‚nt|ƒitƒ}t|ƒitƒ}tt||gƒƒ}tgt|ƒ|||}|ptSt|ŒS(s#Return a relative version of a pathsno path specified( t ValueErrorRRRR3R RRR(R0tstartt start_listt path_listR5trel_list((s%/usr/local/lib/python2.6/posixpath.pyR&…s()t__doc__R:R?R8RQt__all__RRR"RRR RzR!R#RRRRRR9RRRRRRRRRRRRiRRRR$RyR>R%R&(((s%/usr/local/lib/python2.6/posixpath.pyt sZ              '    ­Þ~initial threadšª¶JS‡ ­Þ~initial threadšª¶JS‡Í­Þ~initial threadšª¶J'S‡­Þ~initial threadšª¶J0S‡­Þ~initial threadšª¶J‡S‡­Þ~initial threadšª¶J—S‡­Þ~initial threadšª¶J­S‡¼p¢ÿÿÿ¡ÿÿÿ­Þ~initial threadšª¶J¸S‡/usr/local/lib/python2.6/stat­Þ~initial threadšª¶JÍS‡¼ ­Þ~initial threadšª¶J×S‡p¢ÿÿÿ¶ ­Þ~initial threadšª¶JâS‡/usr/local/lib/python2.6/stat.so­Þ~initial threadšª¶J÷S‡ ­Þ~initial threadšª¶JT‡p¢ÿÿÿ¶&­Þ~initial threadšª¶J T‡/usr/local/lib/python2.6/statmodule.so­Þ~initial threadšª¶J T‡ ­Þ~initial threadšª¶J*T‡p¢ÿÿÿ¶ ­Þ~initial threadšª¶JzT‡/usr/local/lib/python2.6/stat.py­Þ~initial threadšª¶J’T‡­Þ~initial threadšª¶JœT‡½€¡ÿÿÿ}­Þ~initial threadšª¶J¦T‡stat[—%$'¸ô²JÖ²JÖ²J¶Ö²J­Þ~initial threadšª¶J¯T‡½ ­Þ~initial threadšª¶J¹T‡pÿÿÿ¶!­Þ~initial threadšª¶JÃT‡/usr/local/lib/python2.6/stat.pyc­Þ~initial threadšª¶JÚT‡­Þ~initial threadšª¶JäT‡½à›ÿÿÿ}­Þ~initial threadšª¶JîT‡stat[’*$v4ª¶Já²Já²J· Þ²J­Þ~initial threadšª¶J÷T‡½ ­Þ~initial threadšª¶JU‡Í¿ ­Þ~initial threadšª¶JU‡Ñò Ö²Jc@sodZdZdZdZdZdZdZdZdZd Z d Z d „Z d „Z d Z dZdZdZdZdZdZd„Zd„Zd„Zd„Zd„Zd„Zd„ZdZdZeZdZdZdZ d Z!d!Z"dZ#dZ$d Z%d"Z&d#Z'd$Z(d Z)dZ*dZ+dZ,dZ-dZ.dZ/dZ0d Z1d$Z2d%Z3d&Z4d'Z5d(Z6d)Z7d*S(+soConstants/functions for interpreting results of os.stat() and os.lstat(). Suggested usage: from stat import * iiiiiiiiii cCs|d@S(Niÿ((tmode((s /usr/local/lib/python2.6/stat.pytS_IMODEscCs|d@S(Nið((R((s /usr/local/lib/python2.6/stat.pytS_IFMTsi@i i`i€ii iÀcCst|ƒtjS(N(RtS_IFDIR(R((s /usr/local/lib/python2.6/stat.pytS_ISDIR(scCst|ƒtjS(N(RtS_IFCHR(R((s /usr/local/lib/python2.6/stat.pytS_ISCHR+scCst|ƒtjS(N(RtS_IFBLK(R((s /usr/local/lib/python2.6/stat.pytS_ISBLK.scCst|ƒtjS(N(RtS_IFREG(R((s /usr/local/lib/python2.6/stat.pytS_ISREG1scCst|ƒtjS(N(RtS_IFIFO(R((s /usr/local/lib/python2.6/stat.pytS_ISFIFO4scCst|ƒtjS(N(RtS_IFLNK(R((s /usr/local/lib/python2.6/stat.pytS_ISLNK7scCst|ƒtjS(N(RtS_IFSOCK(R((s /usr/local/lib/python2.6/stat.pytS_ISSOCK:siiiii€i@iÀi8i iiiiii N(8t__doc__tST_MODEtST_INOtST_DEVtST_NLINKtST_UIDtST_GIDtST_SIZEtST_ATIMEtST_MTIMEtST_CTIMERRRRRR R R RRRRR R RRtS_ISUIDtS_ISGIDtS_ENFMTtS_ISVTXtS_IREADtS_IWRITEtS_IEXECtS_IRWXUtS_IRUSRtS_IWUSRtS_IXUSRtS_IRWXGtS_IRGRPtS_IWGRPtS_IXGRPtS_IRWXOtS_IROTHtS_IWOTHtS_IXOTHt UF_NODUMPt UF_IMMUTABLEt UF_APPENDt UF_OPAQUEt UF_NOUNLINKt SF_ARCHIVEDt SF_IMMUTABLEt SF_APPENDt SF_NOUNLINKt SF_SNAPSHOT(((s /usr/local/lib/python2.6/stat.pytsn         ­Þ~initial threadšª¶J³U‡· ­Þ~initial threadšª¶JÆU‡½]ÿÿÿ}­Þ~initial threadšª¶JV‡stat[’*$v4šª¶Já²Já²J· Þ²J­Þ~initial threadšª¶JV‡½ ­Þ~initial threadšª¶J(V‡Í­Þ~initial threadšª¶J3V‡­Þ~initial threadšª¶J%$þ«ò²JÖ²JÖ²JÌ Ö²J­Þ~initial threadšª¶J¶W‡½ ­Þ~initial threadšª¶JÀW‡pÿÿÿ¶(­Þ~initial threadšª¶JËW‡/usr/local/lib/python2.6/genericpath.pyc­Þ~initial threadšª¶JâW‡­Þ~initial threadšª¶JìW‡½à›ÿÿÿ}­Þ~initial threadšª¶JöW‡stat[“*$x4ª¶Jà²Jà²J Þ²J­Þ~initial threadšª¶JX‡½ ­Þ~initial threadšª¶J X‡Í ­Þ~initial threadšª¶JX‡Ñò Ö²Jc @s‘dZddkZddkZddddddd d gZd „Zd „Zd „Zd„Zd„Zd„Z d„Z d„Z d„Z dS(s˜ Path operations common to more than one OS Do not use directly. The OS specific modules import the appropriate functions from this module themselves. iÿÿÿÿNt commonprefixtexiststgetatimetgetctimetgetmtimetgetsizetisdirtisfilecCs1yti|ƒ}Wntij otSXtS(sDTest whether a path exists. Returns False for broken symbolic links(toststatterrortFalsetTrue(tpathtst((s'/usr/local/lib/python2.6/genericpath.pyRs cCs=yti|ƒ}Wntij otSXti|iƒS(s%Test whether a path is a regular file(RR R R tS_ISREGtst_mode(R R((s'/usr/local/lib/python2.6/genericpath.pyRs cCs=yti|ƒ}Wntij otSXti|iƒS(s<Return true if the pathname refers to an existing directory.(RR R R tS_ISDIRR(tsR((s'/usr/local/lib/python2.6/genericpath.pyR&s cCsti|ƒiS(s1Return the size of a file, reported by os.stat().(RR tst_size(tfilename((s'/usr/local/lib/python2.6/genericpath.pyR/scCsti|ƒiS(sCReturn the last modification time of a file, reported by os.stat().(RR tst_mtime(R((s'/usr/local/lib/python2.6/genericpath.pyR4scCsti|ƒiS(s=Return the last access time of a file, reported by os.stat().(RR tst_atime(R((s'/usr/local/lib/python2.6/genericpath.pyR9scCsti|ƒiS(sAReturn the metadata change time of a file, reported by os.stat().(RR tst_ctime(R((s'/usr/local/lib/python2.6/genericpath.pyR>scCs_|pdSt|ƒ}t|ƒ}x4t|ƒD]&\}}|||jo || Sq1W|S(sGGiven a list of pathnames, returns the longest common leading componentt(tmintmaxt enumerate(tmts1ts2titc((s'/usr/local/lib/python2.6/genericpath.pyRDs    cCs¯|i|ƒ}|o"|i|ƒ}t||ƒ}n|i|ƒ}||joQ|d}xD||jo2|||jo|| ||fS|d7}qaWn|dfS(s¤Split the extension from a pathname. Extension is everything from the last dot to the end, ignoring leading dots. Returns "(root, ext)"; ext may be empty.iR(trfindR(tptseptaltseptextseptsepIndext altsepIndextdotIndext filenameIndex((s'/usr/local/lib/python2.6/genericpath.pyt _splitextUs   ( t__doc__RR t__all__RRRRRRRRR*(((s'/usr/local/lib/python2.6/genericpath.pyts       ­Þ~initial threadšª¶JuX‡ ­Þ~initial threadšª¶J€X‡½]ÿÿÿ}­Þ~initial threadšª¶J‹X‡stat[“*$x4šª¶Jà²Jà²J Þ²J­Þ~initial threadšª¶J”X‡½ ­Þ~initial threadšª¶JžX‡Í­Þ~initial threadšª¶J©X‡­Þ~initial threadšª¶J²X‡­Þ~initial threadšª¶JåX‡­Þ~initial threadšª¶JõX‡­Þ~initial threadšª¶J Y‡­Þ~initial threadšª¶JY‡­Þ~initial threadšª¶J&Y‡¼p¢ÿÿÿ¡ÿÿÿ!­Þ~initial threadšª¶J1Y‡/usr/local/lib/python2.6/warnings­Þ~initial threadšª¶JFY‡¼ ­Þ~initial threadšª¶JPY‡p¢ÿÿÿ¶$­Þ~initial threadšª¶J[Y‡/usr/local/lib/python2.6/warnings.so­Þ~initial threadšª¶JpY‡ ­Þ~initial threadšª¶JzY‡p¢ÿÿÿ¶*­Þ~initial threadšª¶J…Y‡/usr/local/lib/python2.6/warningsmodule.so­Þ~initial threadšª¶JšY‡ ­Þ~initial threadšª¶J¤Y‡p¢ÿÿÿ¶$­Þ~initial threadšª¶J¯Y‡/usr/local/lib/python2.6/warnings.py­Þ~initial threadšª¶JÆY‡­Þ~initial threadšª¶JÏY‡½€¡ÿÿÿ}­Þ~initial threadšª¶J&Z‡stat[¸%$€"ø²JײJײJ]7ײJ­Þ~initial threadšª¶J0Z‡½ ­Þ~initial threadšª¶J:Z‡pÿÿÿ¶%­Þ~initial threadšª¶JNZ‡/usr/local/lib/python2.6/warnings.pyc­Þ~initial threadšª¶JfZ‡­Þ~initial threadšª¶JpZ‡½à›ÿÿÿ}­Þ~initial threadšª¶JzZ‡stat[Ž*$ Qª¶Jã²Jã²JN3Þ²J­Þ~initial threadšª¶J„Z‡½ ­Þ~initial threadšª¶JŽZ‡ÐË­Þ~initial threadšª¶JZ‡Ñò ײJc @s3dZddkZddkZddkZddddddgZdd d „Zddd „ZeZdd „Z d e d ddd„Z e ddd„Z d„Z defd„ƒYZd„Zd„Zd„Zd„Zdd d„Zdddd„Zdefd„ƒYZdefd„ƒYZeZy>ddklZlZlZlZlZeZeZ e!ZWn%e"j ogZdZhZ nXeei#ƒep€e dd e$d!d ƒe dd e%d!d ƒei&i'Z'e'd jo d"Z(ne'o dZ(ndZ(e e(d e)d!d ƒn[dS(#s&Python part of the warnings subsystem.iÿÿÿÿNtwarnt showwarningt formatwarningtfilterwarningst resetwarningstcatch_warningsicCs=tio/|djo t}nt|||dƒndS(s‡Issue a deprecation warning for Python 3.x related changes. Warnings are omitted unless Python is started with the -3 option. iN(tsyst py3kwarningtNonetDeprecationWarningR(tmessagetcategoryt stacklevel((s$/usr/local/lib/python2.6/warnings.pytwarnpy3ks   c CsW|djo ti}ny#|it|||||ƒƒWntj onXdS(s7Hook to write a warning to a file; replace if you like.N(RRtstderrtwriteRtIOError(R R tfilenametlinenotfiletline((s$/usr/local/lib/python2.6/warnings.pyt _show_warnings   #cCshd|||i|f}|djoti||ƒn|}|o|iƒ}|d|7}n|S(s.Function to format a warning the standard way.s%s:%s: %s: %s s %s N(t__name__Rt linecachetgetlinetstrip(R R RRRts((s$/usr/local/lib/python2.6/warnings.pyR$s & ticCsddk}|djptd |f‚t|tƒp td ‚t|ttifƒp td ‚t|tƒp td ‚t|tƒp td ‚t|t ƒo |djp td‚||i ||i ƒ||i |ƒ|f}|ot i |ƒnt id|ƒdS(s†Insert an entry into the list of warnings filters (at the front). Use assertions to check that all arguments have the right type.iÿÿÿÿNterrortignoretalwaystdefaulttmoduletoncesinvalid action: %rsmessage must be a stringscategory must be a classs#category must be a Warning subclasssmodule must be a stringislineno must be an int >= 0(serrorsignoresalwayssdefaultsmodulesonce(tretAssertionErrort isinstancet basestringttypettypest ClassTypet issubclasstWarningtinttcompiletItfilterstappendtinsert(tactionR R R RR/R"titem((s$/usr/local/lib/python2.6/warnings.pyR-s  cCs†|d jptd|f‚t|tƒo |djp td ‚|d |d |f}|oti|ƒntid|ƒd S( sƒInsert a simple entry into the list of warnings filters (at the front). A simple filter matches all modules and messages. RRRRR R!sinvalid action: %rislineno must be an int >= 0N(serrorsignoresalwayssdefaultsmodulesonce(R#R$R+RR.R/R0(R1R RR/R2((s$/usr/local/lib/python2.6/warnings.pyt simplefilterCs cCs gt(dS(sAClear the list of warning filters, so that no filters are active.N(R.(((s$/usr/local/lib/python2.6/warnings.pyRRst _OptionErrorcBseZdZRS(s,Exception used by option processing helpers.(Rt __module__t__doc__(((s$/usr/local/lib/python2.6/warnings.pyR4VscCs­Þ~initial threadšª¶JÂZ‡­Þ~initial threadšª¶JÌZ‡½]ÿÿÿ}­Þ~initial threadšª¶JÖZ‡stat[Ž*$ Qšª¶Jã²Jã²JN3Þ²J­Þ~initial threadšª¶JßZ‡½ ­Þ~initial threadšª¶JéZ‡ÐË­Þ~initial threadšª¶JöZ‡NxG|D]?}yt|ƒWqtj o}tidI|IJqXqWdS(NsInvalid -W option ignored:(t _setoptionR4RR(targstargtmsg((s$/usr/local/lib/python2.6/warnings.pyt_processoptions[s c Csoddk}|idƒ}t|ƒdjotd|fƒ‚nx%t|ƒdjo|idƒqHWg}|D]}||iƒqx~\}}}}} t|ƒ}|i|ƒ}t|ƒ}|i|ƒ}|o|d}n| oZy't | ƒ} | djo t ‚nWqUt t fj otd| fƒ‚qUXnd} t ||||| ƒdS( Niÿÿÿÿt:istoo many fields (max 5): %rRt$isinvalid lineno %r( R"tsplittlenR4R/Rt _getactiontescapet _getcategoryR+t ValueErrort OverflowErrorR( R9R"tpartst_[1]RR1R R R R((s$/usr/local/lib/python2.6/warnings.pyR7cs0 /    cCs[|pdS|djodSx#d D]}|i|ƒo|Sq%Wtd|fƒ‚dS( NRtallRRR R!Rsinvalid action: %r(sdefaultsalwayssignoresmodulesonceserror(t startswithR4(R1ta((s$/usr/local/lib/python2.6/warnings.pyR@~s  c Cs;ddk}|ptS|id|ƒo=yt|ƒ}Wqtj otd|fƒ‚qXn©|idƒ}|| }||d}yt|dd|gƒ}Wn&t j otd|fƒ‚nXyt ||ƒ}Wn&t j otd|fƒ‚nXt |tƒptd|fƒ‚n|S(Niÿÿÿÿs^[a-zA-Z0-9_]+$sunknown warning category: %rt.isinvalid module name: %rsinvalid warning category: %r( R"R*tmatchtevalt NameErrorR4trfindt __import__Rt ImportErrortgetattrtAttributeErrorR)(R R"tcattiR tklasstm((s$/usr/local/lib/python2.6/warnings.pyRBˆs,  c Cs{t|tƒo |i}n|d jo t}nt|tƒpt‚yti|ƒ}Wn"t j oti }d}nX|i }|i }d|jo|d}nd}|i dƒ}|o.|iƒ}|id ƒo|d }qInP|djo1ytid }Wq8tj o d}q8Xn|p |}n|id hƒ} t|||||| |ƒd S( s:Issue a warning, or maybe ignore it or raise an exception.iRst__file__s.pycs.pyoiÿÿÿÿt__main__it__warningregistry__N(s.pycs.pyo(R$R*t __class__Rt UserWarningR)R#Rt _getframeRCt__dict__t f_globalstf_linenotgettlowertendswithtargvRRt setdefaultt warn_explicit( R R R tcallertglobalsRR Rtfnltregistry((s$/usr/local/lib/python2.6/warnings.pyR£s<           c Cs@t|ƒ}|djo6|pd}|diƒdjo|d }qOn|djo h}nt|tƒot|ƒ}|i}n|}||ƒ}|||f}|i|ƒodSx’tD]„} | \} } } } }| djp| i |ƒoLt || ƒo<| djp| i |ƒo|djp ||joPqÌqÌWt } | djod||iýÿÿÿs.pyiR­Þ~initial threadšª¶J6[‡ ­Þ~initial threadšª¶J@[‡ÐË­Þ~initial threadšª¶JN[‡iRR!RR Rs1Unrecognized action (%r) in warnings.filters: %st func_codet__func__iRsLfunctions overriding warnings.showwarning() must support the 'line' argument(R+RRaR$R*tstrRZR`R.RKR)t defaultactionRtgetlinest onceregistryt RuntimeErrorthasattrRRjRkt co_varnamest co_argcounttco_flagsRRR (R R RRR Ritmodule_globalsttexttkeyR2R1R:RStmodtlntoncekeytaltkeytfxn_codeR8t CO_VARARGStshowwarning_msg((s$/usr/local/lib/python2.6/warnings.pyReËs~                      tWarningMessagecBs,eZdZd Zd d d„Zd„ZRS( s0Holds the result of a single showwarning() call.R R RRRRc CsOtƒ}x%|iD]}t||||ƒqW|o |ind|_dS(N(tlocalst_WARNING_DETAILStsetattrRRt_category_name( tselfR R RRRRt local_valuestattr((s$/usr/local/lib/python2.6/warnings.pyt__init__&s   cCs&d|i|i|i|i|ifS(NsD{message : %r, category : %r, filename : %r, lineno : %s, line : %r}(R RƒRRR(R„((s$/usr/local/lib/python2.6/warnings.pyt__str__-s (smessagescategorysfilenameslinenosfileslineN(RR5R6RRR‡Rˆ(((s$/usr/local/lib/python2.6/warnings.pyRs  cBs8eZdZedd„Zd„Zd„Zd„ZRS(sA context manager that copies and restores the warnings filter upon exiting the context. The 'record' argument specifies whether warnings should be captured by a custom implementation of warnings.showwarning() and be appended to a list returned by the context manager. Otherwise None is returned by the context manager. The objects appended to the list are arguments whose attributes mirror the arguments to showwarning(). The 'module' argument is to specify an alternative module to the module named 'warnings' and imported under that name. This argument is only useful when testing the warnings module itself. cCs:||_|djotidn||_t|_dS(sêSpecify whether to record warnings and if an alternative module should be used other than sys.modules['warnings']. For compatibility with Python 3.0, please consider all arguments to be keyword-only. twarningsN(t_recordRRtmodulest_moduletFalset_entered(R„trecordR ((s$/usr/local/lib/python2.6/warnings.pyR‡Ds $cCsvg}|io|idƒn|itidj o|id|iƒnt|ƒi}d|di|ƒfS(Ns record=TrueR‰s module=%rs%s(%s)s, (RŠR/RŒRR‹R&Rtjoin(R„R8tname((s$/usr/local/lib/python2.6/warnings.pyt__repr__Ps cs|iotd|ƒ‚nt|_|ii|_|i|i_|ii|_|io&g‰‡fd†}||i_ˆSdSdS(NsCannot enter %r twicecsˆit||ŽƒdS(N(R/R(R8tkwargs(tlog(s$/usr/local/lib/python2.6/warnings.pyRbs( RŽRptTrueRŒR.t_filtersRt _showwarningRŠR(R„R((R”s$/usr/local/lib/python2.6/warnings.pyt __enter__Ys    cGs@|iptd|ƒ‚n|i|i_|i|i_dS(Ns%Cannot exit %r without entering first(RŽRpR–RŒR.R—­Þ~initial threadšª¶J¤[‡ ­Þ~initial threadšª¶J¯[‡ÐËV­Þ~initial threadšª¶J½[‡R(R„texc_info((s$/usr/local/lib/python2.6/warnings.pyt__exit__is N( RR5R6RRR‡R’R˜Rš(((s$/usr/local/lib/python2.6/warnings.pyR3s  (R.tdefault_actiont once_registryRReRRR R/R(*R6RRR't__all__RR RRRR*RR3Rt ExceptionR4R;R7R@RBRRetobjectRRRt_warnings_defaultst _warningsR.R›RœRmRoR•RPt warnoptionstPendingDeprecationWarningt ImportWarningtflagst bytes_warningt bytes_actiont BytesWarning(((s$/usr/local/lib/python2.6/warnings.pytsX             )SE(       ­Þ~initial threadšª¶J\‡N ­Þ~initial threadšª¶J\‡ÐË­Þ~initial threadšª¶J)\‡­Þ~initial threadšª¶J2\‡­Þ~initial threadšª¶J¤\‡­Þ~initial threadšª¶J´\‡­Þ~initial threadšª¶JÒ\‡¼ÿÿÿ°Žÿÿÿ"­Þ~initial threadšª¶JÝ\‡/usr/local/lib/python2.6/linecache­Þ~initial threadšª¶Jò\‡¼ ­Þ~initial threadšª¶Jü\‡ÿÿÿ¶%­Þ~initial threadšª¶J]‡/usr/local/lib/python2.6/linecache.so­Þ~initial threadšª¶J]‡ ­Þ~initial threadšª¶J&]‡ÿÿÿ¶+­Þ~initial threadšª¶J1]‡/usr/local/lib/python2.6/linecachemodule.so­Þ~initial threadšª¶JF]‡ ­Þ~initial threadšª¶J]‡ÿÿÿ¶%­Þ~initial threadšª¶J©]‡/usr/local/lib/python2.6/linecache.py­Þ~initial threadšª¶JÁ]‡­Þ~initial threadšª¶JË]‡½ Žÿÿÿ}­Þ~initial threadšª¶JÕ]‡stat[Q%$Þ­ó²JÖ²JÖ²JmÖ²J­Þ~initial threadšª¶JÞ]‡½ ­Þ~initial threadšª¶Jè]‡Šÿÿÿ¶&­Þ~initial threadšª¶Jó]‡/usr/local/lib/python2.6/linecache.pyc­Þ~initial threadšª¶J ^‡­Þ~initial threadšª¶J^‡½‰ÿÿÿ}­Þ~initial threadšª¶J^‡stat[*$ä9ª¶Jà²Jà²J” Þ²J­Þ~initial threadšª¶J&^‡½ ­Þ~initial threadšª¶J1^‡ÐËœ ­Þ~initial threadšª¶J@^‡Ñò Ö²Jc@spdZddkZddkZdddgZdd„Zhad„Zdd„Zdd „Z dd „Z dS( sµCache lines from files. This is intended to read lines from modules imported -- hence if a filename is not found, it will look down the module search path for a file by that name. iÿÿÿÿNtgetlinet clearcachet checkcachecCsHt||ƒ}d|jot|ƒjno ||dSdSdS(Nit(tgetlinestlen(tfilenametlinenotmodule_globalstlines((s%/usr/local/lib/python2.6/linecache.pyR s$ cCs hadS(sClear the cache entirely.N(tcache(((s%/usr/local/lib/python2.6/linecache.pyRscCs+|tjo t|dSt||ƒSdS(ssGet the lines for a file from the cache. Update the cache if it doesn't contain an entry for this file already.iN(R t updatecache(RR((s%/usr/local/lib/python2.6/linecache.pyR!s  cCsÛ|djotiƒ}n|tjo |g}ndSx™|D]‘}t|\}}}}|djoqBnyti|ƒ}Wn tij ot|=qBnX||ijp||ijo t|=qBqBWdS(sUDiscard cache entries that are out of date. (This is not checked upon each call!)N(tNoneR tkeystoststatterrortst_sizetst_mtime(Rt filenamestsizetmtimeR tfullnameR((s%/usr/local/lib/python2.6/linecache.pyR+s"     cCsQ|tjo t|=n| p|d|ddjogS|}yti|ƒ}Wnˆtij oy}tii|ƒd}|oÙd|joÌ|idƒ}|d}t|dd ƒ}|o–|oy||ƒ} Wnt t fj oq_X| d jogSt | ƒd g} | i ƒD]} | | dq+~ |ft|it __loader__t__name__t get_sources itrUN(R RRRtpathtsplittgettgetattrR t ImportErrortIOErrorRt splitlinestsystjoint TypeErrortAttributeErrortopent readlinestcloseRR(RRRRtmsgtbasenametnametloaderRtdatat_[1]tlinetdirnametfpR RR((s%/usr/local/lib/python2.6/linecache.pyR DsX  !   5    ( t__doc__R"Rt__all__R RR RRRR (((s%/usr/local/lib/python2.6/linecache.pyts     ­Þ~initial threadšª¶Je^‡” ­Þ~initial threadšª¶Jo^‡½ Jÿÿÿ}­Þ~initial threadšª¶Jy^‡stat[*$ä9šª¶Jà²Jà²J” Þ²J­Þ~initial threadšª¶J‚^‡½ ­Þ~initial threadšª¶JŒ^‡ÐË­Þ~initial threadšª¶J—^‡­Þ~initial threadšª¶JŸ^‡­Þ~initial threadšª¶JÔ^‡­Þ~initial threadšª¶Jã^‡­Þ~initial threadšª¶Jø^‡­Þ~initial threadšª¶J_‡­Þ~initial threadšª¶JU_‡¼ÿÿÿ°Žÿÿÿ­Þ~initial threadšª¶Ja_‡/usr/local/lib/python2.6/types­Þ~initial threadšª¶Jw_‡¼ ­Þ~initial threadšª¶J_‡ÿÿÿ¶!­Þ~initial threadšª¶JŒ_‡/usr/local/lib/python2.6/types.so­Þ~initial threadšª¶J¡_‡ ­Þ~initial threadšª¶J«_‡ÿÿÿ¶'­Þ~initial threadšª¶Jµ_‡/usr/local/lib/python2.6/typesmodule.so­Þ~initial threadšª¶JÊ_‡ ­Þ~initial threadšª¶J$`‡ÿÿÿ¶!­Þ~initial threadšª¶J0`‡/usr/local/lib/python2.6/types.py­Þ~initial threadšª¶JG`‡­Þ~initial threadšª¶JQ`‡½ Žÿÿÿ}­Þ~initial threadšª¶J[`‡stat[°%$T¼ø²JײJײJ ײJ­Þ~initial threadšª¶Jd`‡½ ­Þ~initial threadšª¶Jn`‡Šÿÿÿ¶"­Þ~initial threadšª¶Jx`‡/usr/local/lib/python2.6/types.pyc­Þ~initial threadšª¶J`‡­Þ~initial threadšª¶J™`‡½‰ÿÿÿ}­Þ~initial threadšª¶J£`‡stat[˜*$“4ª¶Jã²Jã²JT Þ²J­Þ~initial threadšª¶J¬`‡½ ­Þ~initial threadšª¶J¶`‡ÐË\ ­Þ~initial threadšª¶JÅ`‡Ñò ײJc@sodZddkZedƒZeZeZeZ e Z e Z eZy eZWnej onXeZyeZeefZWnej oefZnXeZeZeZeZZ d„Z!ee!ƒZ"ed„ƒZ#yee!i$ƒZ%Wne&j onXd„Z'ee'ƒƒZ(dd d„ƒYZ)ee)ƒZ*ee)i+ƒZ,e)ƒZ-ee-ƒZ.ee-i+ƒZ/ee0ƒZ1egi2ƒZ3eeƒZ4e5Z6e7Z8y e9‚Wnae9j oUy/ei:ƒdZ;ee;ƒZ<ee;i=ƒZ>Wne?j onXdZ;[;nXe@ZAeeBƒZCeeiDƒZEeeFƒZGee"i$ƒZHee"iIƒZJ[[!['[)[-dS( s‹Define names for all type symbols known in the standard interpreter. Types that are part of optional modules (e.g. array) are not listed. iÿÿÿÿNcCsdS(N((((s!/usr/local/lib/python2.6/types.pyt_f*scCsdS(N(tNone(((s!/usr/local/lib/python2.6/types.pyt,sccs dVdS(Ni((((s!/usr/local/lib/python2.6/types.pyt_g3st_CcBseZd„ZRS(cCsdS(N((tself((s!/usr/local/lib/python2.6/types.pyt_m8s(t__name__t __module__R(((s!/usr/local/lib/python2.6/types.pyR7si((Kt__doc__tsysttypeRtNoneTypetTypeTypetobjectt ObjectTypetinttIntTypetlongtLongTypetfloatt FloatTypetboolt BooleanTypetcomplext ComplexTypet NameErrortstrt StringTypetunicodet UnicodeTypet StringTypestbuffert BufferTypettuplet TupleTypetlisttListTypetdicttDictTypetDictionaryTypeRt FunctionTypet LambdaTypet func_codetCodeTypet RuntimeErrorRt GeneratorTypeRt ClassTypeRtUnboundMethodTypet_xt InstanceTypet MethodTypetlentBuiltinFunctionTypetappendtBuiltinMethodTypet ModuleTypetfiletFileTypetxranget XRangeTypet TypeErrortexc_infottbt TracebackTypettb_framet FrameTypetAttributeErrortslicet SliceTypetEllipsist EllipsisTypet__dict__t DictProxyTypetNotImplementedtNotImplementedTypetGetSetDescriptorTypet func_globalstMemberDescriptorType(((s!/usr/local/lib/python2.6/types.pytsx                ­Þ~initial threadšª¶Ja‡T ­Þ~initial threadšª¶Jja‡½ Jÿÿÿ}­Þ~initial threadšª¶Jva‡stat[˜*$“4šª¶Jã²Jã²JT Þ²J­Þ~initial threadšª¶Ja‡½ ­Þ~initial threadšª¶J‰a‡ÐË­Þ~initial threadšª¶J“a‡­Þ~initial threadšª¶Jœa‡­Þ~initial threadšª¶JÌa‡­Þ~initial threadšª¶JÛa‡­Þ~initial threadšª¶JIb‡­Þ~initial threadšª¶JVb‡­Þ~initial threadšª¶JÈb‡­Þ~initial threadšª¶JÖb‡­Þ~initial threadšª¶Jïb‡­Þ~initial threadšª¶Jûb‡­Þ~initial threadšª¶Jˆc‡¼Pµÿÿÿp´ÿÿÿ!­Þ~initial threadšª¶J“c‡/usr/local/lib/python2.6/UserDict­Þ~initial threadšª¶J©c‡¼ ­Þ~initial threadšª¶J³c‡Pµÿÿÿ¶$­Þ~initial threadšª¶J¾c‡/usr/local/lib/python2.6/UserDict.so­Þ~initial threadšª¶JÞc‡ ­Þ~initial threadšª¶Jèc‡Pµÿÿÿ¶*­Þ~initial threadšª¶Jóc‡/usr/local/lib/python2.6/UserDictmodule.so­Þ~initial threadšª¶J d‡ ­Þ~initial threadšª¶Jd‡Pµÿÿÿ¶$­Þ~initial threadšª¶Jd‡/usr/local/lib/python2.6/UserDict.py­Þ~initial threadšª¶Jd‡­Þ~initial threadšª¶J‰d‡½`´ÿÿÿ}­Þ~initial threadšª¶J”d‡stat[%$tî²JÖ²JÖ²J’ Ö²J­Þ~initial threadšª¶Jd‡½ ­Þ~initial threadšª¶J§d‡P°ÿÿÿ¶%­Þ~initial threadšª¶J±d‡/usr/local/lib/python2.6/UserDict.pyc­Þ~initial threadšª¶Jºd‡­Þ~initial threadšª¶Jäd‡½À®ÿÿÿ}­Þ~initial threadšª¶Jïd‡stat[”*$˜5ª¶JÞ²JÞ²Jp#Þ²J­Þ~initial threadšª¶Jød‡½ ­Þ~initial threadšª¶Je‡àÏ­Þ~initial threadšª¶Je‡Ñò Ö²Jc@sbdZdd d„ƒYZdefd„ƒYZddkZeiieƒdd d„ƒYZdS( sGA more or less complete user-defined wrapper around dictionary objects.tUserDictcBsìeZdd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z d „Zd „Zd „Zd„Zd„Zdd„Zdd„Zdd„Zd„Zd„Zd„Zedd„ƒZRS(cKsIh|_|dj o|i|ƒnt|ƒo|i|ƒndS(N(tdatatNonetupdatetlen(tselftdicttkwargs((s$/usr/local/lib/python2.6/UserDict.pyt__init__s    cCs t|iƒS(N(treprR(R((s$/usr/local/lib/python2.6/UserDict.pyt__repr__ scCs8t|tƒot|i|iƒSt|i|ƒSdS(N(t isinstanceRtcmpR(RR((s$/usr/local/lib/python2.6/UserDict.pyt__cmp__ scCs t|iƒS(N(RR(R((s$/usr/local/lib/python2.6/UserDict.pyt__len__scCsS||ijo |i|St|idƒo|ii||ƒSt|ƒ‚dS(Nt __missing__(Rthasattrt __class__RtKeyError(Rtkey((s$/usr/local/lib/python2.6/UserDict.pyt __getitem__s  cCs||i|s K ­Þ~initial threadšª¶JFf‡p ­Þ~initial threadšª¶JQf‡àÏ­Þ~initial threadšª¶J\f‡­Þ~initial threadšª¶Jdf‡­Þ~initial threadšª¶J¨f‡­Þ~initial threadšª¶J·f‡­Þ~initial threadšª¶Jâf‡¼p¢ÿÿÿ¡ÿÿÿ ­Þ~initial threadšª¶Jíf‡/usr/local/lib/python2.6/_abcoll­Þ~initial threadšª¶Jg‡¼ ­Þ~initial threadšª¶J g‡p¢ÿÿÿ¶#­Þ~initial threadšª¶Jg‡/usr/local/lib/python2.6/_abcoll.so­Þ~initial threadšª¶J,g‡ ­Þ~initial threadšª¶J6g‡p¢ÿÿÿ¶)­Þ~initial threadšª¶J@g‡/usr/local/lib/python2.6/_abcollmodule.so­Þ~initial threadšª¶JUg‡ ­Þ~initial threadšª¶J_g‡p¢ÿÿÿ¶#­Þ~initial threadšª¶J±g‡/usr/local/lib/python2.6/_abcoll.py­Þ~initial threadšª¶JÉg‡­Þ~initial threadšª¶JÓg‡½€¡ÿÿÿ}­Þ~initial threadšª¶JÝg‡stat[ %$Hî²JÖ²JÖ²J95Ö²J­Þ~initial threadšª¶Jæg‡½ ­Þ~initial threadšª¶Jðg‡pÿÿÿ¶$­Þ~initial threadšª¶Júg‡/usr/local/lib/python2.6/_abcoll.pyc­Þ~initial threadšª¶Jh‡­Þ~initial threadšª¶Jh‡½à›ÿÿÿ}­Þ~initial threadšª¶J%h‡stat[•*$€4ª¶JÞ²JÞ²J0V,Þ²J­Þ~initial threadšª¶J.h‡½ ­Þ~initial threadšª¶J8h‡àÏ­Þ~initial threadšª¶JHh‡Ñò Ö²Jc@s@dZddklZlZddkZdddddd d d d d ddddddgZdd$d„ƒYZdd%d„ƒYZeie ƒdefd„ƒYZ dd&d„ƒYZ dd'd„ƒYZ d d(d„ƒYZ d e ee fd„ƒYZeieƒd efd„ƒYZeieƒd e ee fd„ƒYZde fd„ƒYZdeefd„ƒYZdeefd„ƒYZdefd „ƒYZd efd!„ƒYZeieƒde ee fd"„ƒYZeieƒeieƒeieƒeieƒdefd#„ƒYZeieƒdS()sAbstract Base Classes (ABCs) for collections, according to PEP 3119. DON'T USE THIS MODULE DIRECTLY! The classes here should be imported via collections; they are defined here only to alleviate certain bootstrapping issues. Unit tests are in test_collections. iÿÿÿÿ(tABCMetatabstractmethodNtHashabletIterabletIteratortSizedt ContainertCallabletSett MutableSettMappingtMutableMappingt MappingViewtKeysViewt ItemsViewt ValuesViewtSequencetMutableSequencecBs,eZeZed„ƒZed„ƒZRS(cCsdS(Ni((tself((s#/usr/local/lib/python2.6/_abcoll.pyt__hash__scCsQ|tjo@x=|iD].}d|ijo|idotSPqqWntS(NR(Rt__mro__t__dict__tTruetNotImplemented(tclstCtB((s#/usr/local/lib/python2.6/_abcoll.pyt__subclasshook__s   (t__name__t __module__Rt __metaclass__RRt classmethodR(((s#/usr/local/lib/python2.6/_abcoll.pyRscBs,eZeZed„ƒZed„ƒZRS(ccsxto dVqWdS(N(tFalsetNone(R((s#/usr/local/lib/python2.6/_abcoll.pyt__iter__-scCs4|tjo#td„|iDƒƒotSntS(Ncss"x|]}d|ijVqWdS(R"N(R(t.0R((s#/usr/local/lib/python2.6/_abcoll.pys 5s (RtanyRRR(RR((s#/usr/local/lib/python2.6/_abcoll.pyR2s  (RRRRRR"RR(((s#/usr/local/lib/python2.6/_abcoll.pyR*scBs/eZed„ƒZd„Zed„ƒZRS(cCs t‚dS(N(t StopIteration(R((s#/usr/local/lib/python2.6/_abcoll.pytnext>scCs|S(N((R((s#/usr/local/lib/python2.6/_abcoll.pyR"BscCs4|tjo#td„|iDƒƒotSntS(Ncss"x|]}d|ijVqWdS(R&N(R(R#R((s#/usr/local/lib/python2.6/_abcoll.pys Hs (RR$RRR(RR((s#/usr/local/lib/python2.6/_abcoll.pyREs  (RRRR&R"RR(((s#/usr/local/lib/python2.6/_abcoll.pyR<s cBs,eZeZed„ƒZed„ƒZRS(cCsdS(Ni((R((s#/usr/local/lib/python2.6/_abcoll.pyt__len__PscCs4|tjo#td„|iDƒƒotSntS(Ncss"x|]}d|ijVqWdS(R'N(R(R#R((s#/usr/local/lib/python2.6/_abcoll.pys Ws (RR$RRR(RR((s#/usr/local/lib/python2.6/_abcoll.pyRTs  (RRRRRR'RR(((s#/usr/local/lib/python2.6/_abcoll.pyRMscBs,eZeZed„ƒZed„ƒZRS(c­Þ~initial threadšª¶Jªh‡­Þ~initial threadšª¶J´h‡½]ÿÿÿ}­Þ~initial threadšª¶J¿h‡stat[•*$€4šª¶JÞ²JÞ²J0V,Þ²J­Þ~initial threadšª¶JÈh‡½ ­Þ~initial threadšª¶Ji‡àÏ­Þ~initial threadšª¶J!i‡CstS(N(R (Rtx((s#/usr/local/lib/python2.6/_abcoll.pyt __contains___scCs4|tjo#td„|iDƒƒotSntS(Ncss"x|]}d|ijVqWdS(R)N(R(R#R((s#/usr/local/lib/python2.6/_abcoll.pys fs (RR$RRR(RR((s#/usr/local/lib/python2.6/_abcoll.pyRcs  (RRRRRR)RR(((s#/usr/local/lib/python2.6/_abcoll.pyR\scBs,eZeZed„ƒZed„ƒZRS(cOstS(N(R (Rtargstkwds((s#/usr/local/lib/python2.6/_abcoll.pyt__call__nscCs4|tjo#td„|iDƒƒotSntS(Ncss"x|]}d|ijVqWdS(R,N(R(R#R((s#/usr/local/lib/python2.6/_abcoll.pys us (RR$RRR(RR((s#/usr/local/lib/python2.6/_abcoll.pyRrs  (RRRRRR,RR(((s#/usr/local/lib/python2.6/_abcoll.pyRkscBseZdZd„Zd„Zd„Zd„Zd„Zd„Ze d„ƒZ d„Z d „Z d „Z d „Zd „ZdZd „ZRS(shA set is a finite, iterable container. This class provides concrete generic implementations of all methods except for __contains__, __iter__ and __len__. To override the comparisons (presumably for speed, as the semantics are fixed), all you have to do is redefine __le__ and then the other operations will automatically follow suit. cCsZt|tƒptSt|ƒt|ƒjotSx |D]}||jotSq:WtS(N(t isinstanceRRtlenR R(Rtothertelem((s#/usr/local/lib/python2.6/_abcoll.pyt__le__ˆs  cCs;t|tƒptSt|ƒt|ƒjo |i|ƒS(N(R-RRR.R1(RR/((s#/usr/local/lib/python2.6/_abcoll.pyt__lt__’scCst|tƒptS||jS(N(R-RR(RR/((s#/usr/local/lib/python2.6/_abcoll.pyt__gt__—scCst|tƒptS||jS(N(R-RR(RR/((s#/usr/local/lib/python2.6/_abcoll.pyt__ge__œscCs;t|tƒptSt|ƒt|ƒjo |i|ƒS(N(R-RRR.R1(RR/((s#/usr/local/lib/python2.6/_abcoll.pyt__eq__¡scCs ||j S(N((RR/((s#/usr/local/lib/python2.6/_abcoll.pyt__ne__¦scCs ||ƒS(s¼Construct an instance of the class from any iterable input. Must override this method if the class constructor signature does not accept an iterable for an input. ((Rtit((s#/usr/local/lib/python2.6/_abcoll.pyt_from_iterable©scs2t|tƒptSˆi‡fd†|DƒƒS(Nc3s*x#|]}|ˆjo |VqqWdS(N((R#tvalue(R(s#/usr/local/lib/python2.6/_abcoll.pys µs (R-RRR8(RR/((Rs#/usr/local/lib/python2.6/_abcoll.pyt__and__²scCs'x |D]}||jotSqWtS(N(R R(RR/R9((s#/usr/local/lib/python2.6/_abcoll.pyt isdisjoint·s   cCs8t|tƒptSd„||fDƒ}|i|ƒS(Ncss*x#|]}x|D] }|VqWqWdS(N((R#tste((­Þ~initial threadšª¶Jni‡ ­Þ~initial threadšª¶Jyi‡àÏ­Þ~initial threadšª¶J‡i‡s#/usr/local/lib/python2.6/_abcoll.pys Às (R-RRR8(RR/tchain((s#/usr/local/lib/python2.6/_abcoll.pyt__or__½scsUtˆtƒp(tˆtƒptS|iˆƒ‰n|i‡fd†|DƒƒS(Nc3s*x#|]}|ˆjo |VqqWdS(N((R#R9(R/(s#/usr/local/lib/python2.6/_abcoll.pys Ès (R-RRRR8(RR/((R/s#/usr/local/lib/python2.6/_abcoll.pyt__sub__Ãs cCsHt|tƒp(t|tƒptS|i|ƒ}n||||BS(N(R-RRRR8(RR/((s#/usr/local/lib/python2.6/_abcoll.pyt__xor__Ës cCsÎti}d|d}t|ƒ}d|d}||M}x>|D]6}t|ƒ}|||d>AdAdN}||M}qBW|dd}||M}||jo||d8}n|d jo d }n|S( s+Compute the hash value of a set. Note that we don't define __hash__: not all sets are hashable. But if you define a hashable set type, its __hash__ should call this function. This must be compatible __eq__. All sets ought to compare equal if they contain the same elements, regardless of how they are implemented, and regardless of the order of the elements; so there's not much freedom for __eq__ or __hash__. We match the algorithm used by the built-in frozenset type. iiiMïèrii³M[I×4?ÙiÍ iãÃ6iÿÿÿÿiÁÇ8#(tsystmaxintR.thash(RtMAXtMASKtnthR(thx((s#/usr/local/lib/python2.6/_abcoll.pyt_hashÕs"        N(RRt__doc__R1R2R3R4R5R6RR8R:R;R?R@RAR!RRJ(((s#/usr/local/lib/python2.6/_abcoll.pyR}s           cBseeZed„ƒZed„ƒZd„Zd„Zd„Zd„Zd„Z d„Z d„Z RS( cCs t‚dS(sAdd an element.N(tNotImplementedError(RR9((s#/usr/local/lib/python2.6/_abcoll.pytaddúscCs t‚dS(s8Remove an element. Do not raise an exception if absent.N(RL(RR9((s#/usr/local/lib/python2.6/_abcoll.pytdiscardÿscCs.||jot|ƒ‚n|i|ƒdS(s5Remove an element. If not a member, raise a KeyError.N(tKeyErrorRN(RR9((s#/usr/local/lib/python2.6/_abcoll.pytremoves cCsIt|ƒ}yt|ƒ}Wntj o t‚nX|i|ƒ|S(s2Return the popped value. Raise KeyError if empty.(titerR&R%RORN(RR7R9((s#/usr/local/lib/python2.6/_abcoll.pytpop s   cCs7yxto|iƒqWWntj onXdS(s6This is slow (creates N new iterators!) but effective.N(RRRRO(R((s#/usr/local/lib/python2.6/_abcoll.pytclears cCs"x|D]}|i|ƒqW|S(N(RM(RR7R9((s#/usr/local/lib/python2.6/_abcoll.pyt__ior__scCs&x||D]}|i|ƒq W|S(N(RN(RR7R9((s#/usr/local/lib/python2.6/_abcoll.pyt__iand__!s cCsct|tƒp|i|ƒ}nx9|D]1}||jo|i|ƒq*|i|ƒq*W|S(N(R-RR8RNRM(RR7R9((s#/usr/local/lib/python2.6/_abcoll.pyt__ixor__&s cCs"x|D]}|i|ƒqW|S(N(RN(RR7R9((s#/usr/local­Þ~initial threadšª¶J¬i‡ ­Þ~initial threadšª¶Jj‡àÏ­Þ~initial threadšª¶Jj‡/lib/python2.6/_abcoll.pyt__isub__0s( RRRRMRNRPRRRSRTRURVRW(((s#/usr/local/lib/python2.6/_abcoll.pyR øs     cBszeZed„ƒZd d„Zd„Zd„Zd„Zd„Z d„Z d„Z d„Z d Z d „Zd „ZRS( cCs t‚dS(N(RO(Rtkey((s#/usr/local/lib/python2.6/_abcoll.pyt __getitem__=scCs'y ||SWntj o|SXdS(N(RO(RRXtdefault((s#/usr/local/lib/python2.6/_abcoll.pytgetAs cCs+y ||Wntj otSXtSdS(N(ROR R(RRX((s#/usr/local/lib/python2.6/_abcoll.pyR)Gs  cCs t|ƒS(N(RQ(R((s#/usr/local/lib/python2.6/_abcoll.pytiterkeysOsccsx|D]}||VqWdS(N((RRX((s#/usr/local/lib/python2.6/_abcoll.pyt itervaluesRsccs$x|D]}|||fVqWdS(N((RRX((s#/usr/local/lib/python2.6/_abcoll.pyt iteritemsVscCs t|ƒS(N(tlist(R((s#/usr/local/lib/python2.6/_abcoll.pytkeysZscCs)g}|D]}||||fq ~S(N((Rt_[1]RX((s#/usr/local/lib/python2.6/_abcoll.pytitems]scCs#g}|D]}|||q ~S(N((RRaRX((s#/usr/local/lib/python2.6/_abcoll.pytvalues`scCs2t|tƒo"t|iƒƒt|iƒƒjS(N(R-R tdictRb(RR/((s#/usr/local/lib/python2.6/_abcoll.pyR5fscCs ||j S(N((RR/((s#/usr/local/lib/python2.6/_abcoll.pyR6jsN(RRRRYR!R[R)R\R]R^R`RbRcRR5R6(((s#/usr/local/lib/python2.6/_abcoll.pyR ;s         cBseZd„Zd„ZRS(cCs ||_dS(N(t_mapping(Rtmapping((s#/usr/local/lib/python2.6/_abcoll.pyt__init__oscCs t|iƒS(N(R.Re(R((s#/usr/local/lib/python2.6/_abcoll.pyR'rs(RRRgR'(((s#/usr/local/lib/python2.6/_abcoll.pyR ms cBseZd„Zd„ZRS(cCs ||ijS(N(Re(RRX((s#/usr/local/lib/python2.6/_abcoll.pyR)xsccsx|iD] }|Vq WdS(N(Re(RRX((s#/usr/local/lib/python2.6/_abcoll.pyR"{s (RRR)R"(((s#/usr/local/lib/python2.6/_abcoll.pyR vs cBseZd„Zd„ZRS(cCsB|\}}y|i|}Wntj otSX||jSdS(N(ReROR (RtitemRXR9tv((s#/usr/local/lib/python2.6/_abcoll.pyR)‚s  ccs*x#|iD]}||i|fVq WdS(N(Re(RRX((s#/usr/local/lib/python2.6/_abcoll.pyR"‹s (RRR)R"(((s#/usr/local/lib/python2.6/_abcoll.pyR€s cBseZd„Zd„ZRS(cCs1x*|iD]}||i|jotSq WtS(N(ReRR (RR9RX((s#/usr/local/lib/python2.6/_abcoll.pyR)’s   ccs$x|iD]}|i|Vq WdS(N(Re(RRX((s#/usr/local/lib/python2.6/_abcoll.pyR"˜s (RR­Þ~initial threadšª¶Jbj‡ ­Þ~initial threadšª¶Jmj‡àÏ­Þ~initial threadšª¶J|j‡R)R"(((s#/usr/local/lib/python2.6/_abcoll.pyRs cBseeZed„ƒZed„ƒZeƒZed„Zd„Zd„Z dd„Z dd„Z RS( cCs t‚dS(N(RO(RRXR9((s#/usr/local/lib/python2.6/_abcoll.pyt __setitem__ŸscCs t‚dS(N(RO(RRX((s#/usr/local/lib/python2.6/_abcoll.pyt __delitem__£scCsKy||}Wn+tj o||ijo‚n|SX||=|SdS(N(ROt_MutableMapping__marker(RRXRZR9((s#/usr/local/lib/python2.6/_abcoll.pyRR©scCsMytt|ƒƒ}Wntj o t‚nX||}||=||fS(N(R&RQR%RO(RRXR9((s#/usr/local/lib/python2.6/_abcoll.pytpopitem´s  cCs7yxto|iƒqWWntj onXdS(N(RRmRO(R((s#/usr/local/lib/python2.6/_abcoll.pyRS½s cKs¸t|tƒo#xz|D]}||||s (tsum(RR9((R9s#/usr/local/lib/python2.6/_abcoll.pytcounts( RRRKRRYR"R)RwRsR{(((s#/usr/local/lib/python2.6/_abcoll.pyRÞs   cBsneZed„ƒZed„ƒZed„ƒZd„Zd„Zd„Zdd„Z d„Z d „Z RS( cCs t‚dS(N(Rr(RRsR9((s#/usr/local/lib/python2.6/_abcoll.pyRjscCs t‚dS(N(Rr(RRs((s#/usr/local/lib/python2.6/_abcoll.pyRkscCs t‚dS(N(Rr(RRsR9((s#/usr/local/lib­Þ~initial threadšª¶JÑj‡ ­Þ~initial threadšª¶JÜj‡àÏ8­Þ~initial threadšª¶Jêj‡/python2.6/_abcoll.pytinsertscCs|it|ƒ|ƒdS(N(R|R.(RR9((s#/usr/local/lib/python2.6/_abcoll.pytappendscCsXt|ƒ}xEt|dƒD]3}|||d||||<|||d sB      x = 2   ; (    %­Þ~initial threadšª¶J;k‡0 ­Þ~initial threadšª¶JFk‡àÏ­Þ~initial threadšª¶JPk‡­Þ~initial threadšª¶JYk‡­Þ~initial threadšª¶J6l‡­Þ~initial threadšª¶JFl‡­Þ~initial threadšª¶JZl‡¼ÿÿÿ°Žÿÿÿ­Þ~initial threadšª¶Jel‡/usr/local/lib/python2.6/abc­Þ~initial threadšª¶J{l‡¼ ­Þ~initial threadšª¶J…l‡ÿÿÿ¶­Þ~initial threadšª¶Jl‡/usr/local/lib/python2.6/abc.so­Þ~initial threadšª¶J¥l‡ ­Þ~initial threadšª¶J¯l‡ÿÿÿ¶%­Þ~initial threadšª¶Jºl‡/usr/local/lib/python2.6/abcmodule.so­Þ~initial threadšª¶JÏl‡ ­Þ~initial threadšª¶JÙl‡ÿÿÿ¶­Þ~initial threadšª¶Jäl‡/usr/local/lib/python2.6/abc.py­Þ~initial threadšª¶Júl‡­Þ~initial threadšª¶Jm‡½ Žÿÿÿ}­Þ~initial threadšª¶Jm‡stat[%$Äqî²JÖ²JÖ²JÖÖ²J­Þ~initial threadšª¶Jm‡½ ­Þ~initial threadšª¶J!m‡Šÿÿÿ¶ ­Þ~initial threadšª¶J,m‡/usr/local/lib/python2.6/abc.pyc­Þ~initial threadšª¶J,n‡­Þ~initial threadšª¶J8n‡½‰ÿÿÿ}­Þ~initial threadšª¶JDn‡stat[–*$Š4ª¶JÞ²JÞ²J  Þ²J­Þ~initial threadšª¶JNn‡½ ­Þ~initial threadšª¶JZn‡àÏ­Þ~initial threadšª¶Jkn‡Ñò Ö²Jc@s?dZd„Zdefd„ƒYZdefd„ƒYZdS(s3Abstract Base Classes (ABCs) according to PEP 3119.cCs t|_|S(sóA decorator indicating abstract methods. Requires that the metaclass is ABCMeta or derived from it. A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract methods are overridden. The abstract methods can be called using any of the the normal 'super' call mechanisms. Usage: class C: __metaclass__ = ABCMeta @abstractmethod def my_abstract_method(self, ...): ... (tTruet__isabstractmethod__(tfuncobj((s/usr/local/lib/python2.6/abc.pytabstractmethods tabstractpropertycBseZdZeZRS(s3A decorator indicating abstract properties. Requires that the metaclass is ABCMeta or derived from it. A class that has a metaclass derived from ABCMeta cannot be instantiated unless all of its abstract properties are overridden. The abstract properties can be called using any of the the normal 'super' call mechanisms. Usage: class C: __metaclass__ = ABCMeta @abstractproperty def my_abstract_property(self): ... This defines a read-only property; you can also define a read-write abstract property using the 'long' form of property declaration: class C: __metaclass__ = ABCMeta def getx(self): ... def setx(self, value): ... x = abstractproperty(getx, setx) (t__name__t __module__t__doc__RR(((s/usr/local/lib/python2.6/abc.pyRstABCMetacBsDeZdZdZd„Zd„Zdd„Zd„Zd„Z RS(siMetaclass for defining Abstract Base Classes (ABCs). Use this metaclass to create an ABC. An ABC can be subclassed directly, and then acts as a mix-in class. You can also register unrelated concrete classes (even built-in classes) and unrelated ABCs as 'virtual subclasses' -- these and their descendants will be considered subclasses of the registering ABC by the built-in issubclass() function, but the registering ABC won't show up in their MRO (Method Resolution Order) nor will method implementations defined by the registering ABC be callable (not even via super()). icCsçtt|ƒi||||ƒ}td„|iƒDƒƒ}xd|D]\}xSt|dtƒƒD]<}t||dƒ}t|dtƒo|i|ƒq`q`WqDWt |ƒ|_ tƒ|_ tƒ|_ tƒ|_ ti|_|S(Ncss6x/|](\}}t|dtƒo |VqqWdS(RN(tgetattrtFalse(t.0tnametvalue((s/usr/local/lib/python2.6/abc.pys Qs  t__abstractmethods__R(tsuperRt__new__tsettitemsR tNoneR taddt frozensetRt _abc_registryt _abc_cachet_abc_negative_cachet_abc_invalidation_countert_abc_negative_cache_version(tmclsR tbasest namespacetclst abstractstbaseR ((s/usr/local/lib/python2.6/abc.pyRNs !     cCsxt|tƒptdƒ‚nt||ƒodSt||ƒotdƒ‚n|ii|ƒtid7_dS(s&Register a virtual subclass of an ABC.sCan only register classesNs'Refusing to create an inheritance cyclei( t isinstancettypet TypeErrort issubclasst RuntimeErrorRRRR(Rtsubclass((s/usr/local/lib/python2.6/abc.pytregisterascCs†|d|i|ifIJ|dtiIJxTt|iiƒƒD]=}|idƒo't||ƒ}|d||fIJqAqA­Þ~initial threadšª¶Jvn‡­Þ~initial threadšª¶Jn‡½ Jÿÿÿ}­Þ~initial threadšª¶Jn‡stat[–*$Š4šª¶JÞ²JÞ²J  Þ²J­Þ~initial threadšª¶J©n‡½ ­Þ~initial threadšª¶Jµn‡àÏ­Þ~initial threadšª¶JÄn‡WdS(s'Debug helper to print the ABC registry.s Class: %s.%ssInv.counter: %st_abc_s%s: %rN( RRRRtsortedt__dict__tkeyst startswithR (RtfileR R ((s/usr/local/lib/python2.6/abc.pyt_dump_registryoscCs t|ddƒ}||ijotSt|ƒ}||jp |djo6|itijo||ijot S|i |ƒS|i |ƒp |i |ƒS(s'Override for isinstance(instance, cls).t __class__N( R RRRR"RRRRR t__subclasscheck__(RtinstanceR&tsubtype((s/usr/local/lib/python2.6/abc.pyt__instancecheck__xs  cCss||ijotS|itijotƒ|_ti|_n||ijotS|i|ƒ}|t j oGt |t ƒpt ‚|o|ii |ƒn|ii |ƒ|S|t|ddƒjo|ii |ƒtSx6|iD]+}t||ƒo|ii |ƒtSqôWx9|iƒD]+}t||ƒo|ii |ƒtSq0W|ii |ƒtS(s'Override for issubclass(subclass, cls).t__mro__((RRRRRRRR t__subclasshook__tNotImplementedR!tbooltAssertionErrorRR RR$t__subclasses__(RR&toktrclstscls((s/usr/local/lib/python2.6/abc.pyR0‰s:      N( RRRRRR'RR.R3R0(((s/usr/local/lib/python2.6/abc.pyR9s   N(RRtpropertyRR"R(((s/usr/local/lib/python2.6/abc.pyts ­Þ~initial threadšª¶JÏn‡  ­Þ~initial threadšª¶JÚn‡àÏ­Þ~initial threadšª¶Jæn‡­Þ~initial threadšª¶Jðn‡­Þ~initial threadšª¶Jo‡­Þ~initial threadšª¶J+o‡­Þ~initial threadšª¶Jmq‡­Þ~initial threadšª¶J|q‡­Þ~initial threadšª¶Jv‡­Þ~initial threadšª¶J/v‡­Þ~initial threadšª¶J]v‡­Þ~initial threadšª¶Jkv‡­Þ~initial threadšª¶Jä{‡¼Pµÿÿÿp´ÿÿÿ!­Þ~initial threadšª¶Jò{‡/usr/local/lib/python2.6/copy_reg­Þ~initial threadšª¶J |‡¼ ­Þ~initial threadšª¶J|‡Pµÿÿÿ¶$­Þ~initial threadšª¶J"|‡/usr/local/lib/python2.6/copy_reg.so­Þ~initial threadšª¶J9|‡ ­Þ~initial threadšª¶JD|‡Pµÿÿÿ¶*­Þ~initial threadšª¶JP|‡/usr/local/lib/python2.6/copy_regmodule.so­Þ~initial threadšª¶J{|‡ ­Þ~initial threadšª¶Jˆ|‡Pµÿÿÿ¶$­Þ~initial threadšª¶J”|‡/usr/local/lib/python2.6/copy_reg.py­Þ~initial threadšª¶J­|‡­Þ~initial threadšª¶J¹|‡½`´ÿÿÿ}­Þ~initial threadšª¶JÅ|‡stat[+%$äuï²JÖ²JÖ²JÖ²J­Þ~initial threadšª¶JÏ|‡½ ­Þ~initial threadšª¶JÚ|‡P°ÿÿÿ¶%­Þ~initial threadšª¶Jæ|‡/usr/local/lib/python2.6/copy_reg.pyc­Þ~initial threadšª¶Jþ|‡­Þ~initial threadšª¶J }‡½À®ÿÿÿ}­Þ~initial threadšª¶J}‡stat[—*$è7ª¶Jß²Jß²Jf Þ²J­Þ~initial threadšª¶J}‡½ ­Þ~initial threadšª¶J*}‡àÏ­Þ~initial threadšª¶J;}‡Ñò Ö²Jc@sØdZddklZdddddgZhZdd„Zd „Zye Wne j onXd „Z ee e e ƒd „Z dZ d„Zd„Zd„ZhZhZhZd„Zd„Zd„ZdS(s¬Helper to provide extensibility for pickle/cPickle. This is only useful to add pickle support for extension types defined in C, not for instances of user-defined classes. iÿÿÿÿ(t ClassTypetpicklet constructort add_extensiontremove_extensiontclear_extension_cachecCslt|ƒtjotdƒ‚nt|dƒptdƒ‚n|t|<|dj ot|ƒndS(Ns-copy_reg is not intended for use with classest__call__s$reduction functions must be callable(ttypet _ClassTypet TypeErrorthasattrtdispatch_tabletNoneR(tob_typetpickle_functiontconstructor_ob((s$/usr/local/lib/python2.6/copy_reg.pyRs  cCs$t|dƒptdƒ‚ndS(NRsconstructors must be callable(R R (tobject((s$/usr/local/lib/python2.6/copy_reg.pyRscCst|i|iffS(N(tcomplextrealtimag(tc((s$/usr/local/lib/python2.6/copy_reg.pytpickle_complex'scCs]|tjoti|ƒ}n:|i||ƒ}|itijo|i||ƒn|S(N(Rt__new__t__init__(tclstbasetstatetobj((s$/usr/local/lib/python2.6/copy_reg.pyt_reconstructor.s  ii cCsI|djpt‚x>|iiD]*}t|dƒo|it@ oPq!q!Wt}|tjo d}n1||ijotd|i ‚n||ƒ}|i||f}y |i }Wn_t j oSt |ddƒotdƒ‚ny |i }Wq&t j o d}q&Xn X|ƒ}|ot||fSt|fSdS(Nit __flags__scan't pickle %s objectst __slots__sNa class that defines __slots__ without defining __getstate__ cannot be pickled(tAssertionErrort __class__t__mro__R Rt _HEAPTYPERR R t__name__t __getstate__tAttributeErrortgetattrt__dict__R(tselftprotoRRtargstgetstatetdict((s$/usr/local/lib/python2.6/copy_reg.pyt _reduce_ex;s2        cGs|i||ŒS(N(R(RR*((s$/usr/local/lib/python2.6/copy_reg.pyt __newobj__\scCs|iidƒ}|dj o|Sg}t|dƒpnÄxÀ|iD]µ}d|ijoŸ|id}t|tƒo |f}nxr|D]f}|djoqq|idƒo/|idƒ o|i d|i |fƒq|i |ƒqWqHqHWy ||_ WnnX|S( s›Return a list of slot names for a given class. This needs to find slots defined by the class and its bases, so we can't simply return the __slots__ attribute. We must walk down the Method Resolution Order and concatenate the __slots__ of each class found there. (This assumes classes don't modify their __slots__ attribute to misrepresent their slots after the class is defined.) t __slotnames__RR't __weakref__t__s_%s%sN(s__dict__s __weakref__( R'tgetR R R!t isinstancet basestringt startswithtendswithtappendR#R/(RtnamesRtslotstname((s$/usr/local/lib/python2.6/copy_reg.pyt _slotnames_s0      ! cCsât|ƒ}d|jo djnp td‚n||f}ti|ƒ|joti|ƒ|jodS|tjotd|t|fƒ‚n|tjotd|t|fƒ‚n|t|<|t|R2R?R=t_extension_cache(R@R:RARB((s$/usr/local/lib/python2.6/copy_reg.pyR¯s  cCstiƒdS(N(RCtclear(((s$/usr/local/lib/python2.6/copy_reg.pyR»sNi(t__doc__ttypesRRt__all__R R RRRt NameErrorRRR"R-R.R;R>R?RCRRR(((s$/usr/local/lib/python2.6/copy_reg.pyts.    !  8  ­Þ~initial threadšª¶JŒ}‡f ­Þ~initial threadšª¶J—}‡àÏ­Þ~initial threadšª¶J£}‡­Þ~initial threadšª¶J­}‡­Þ~initial threadšª¶J®‡­Þ~initial threadšª¶JÀ‡­Þ~initial threadšª¶J €‡­Þ~initial threadšª¶J€‡­Þ~initial threadšª¶J쀇­Þ~initial threadšª¶J&‡­Þ~initial threadšª¶Jy‚‡­Þ~initial threadšª¶J…‚‡é­Þ~initial threadšª¶J“‚‡­Þ~initial threadšª¶J‚‡é­Þ~initial threadšª¶J«‚‡+­Þ~initial threadšª¶Jµ‚‡+é­Þ~initial threadšª¶JÁ‚‡/­Þ~initial threadšª¶JË‚‡/é­Þ~initial threadšª¶J÷‚‡¼ÐÀÆÐÈÿÿÿ,­Þ~initial threadšª¶Jƒ‡/home/gnn/.local/lib/python2.6/site-packages­Þ~initial threadšª¶Jƒ‡¼­Þ~initial threadšª¶JMƒ‡¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶JYƒ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jqƒ‡¼­Þ~initial threadšª¶J|ƒ‡¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶J‡ƒ‡/usr/share/nls/libc/C­Þ~initial threadšª¶J›ƒ‡¼­Þ~initial threadšª¶J§ƒ‡¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶J¼ƒ‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÖƒ‡¼­Þ~initial threadšª¶JჇ¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶J샇/usr/local/share/nls/libc/C­Þ~initial threadšª¶J„‡¼­Þ~initial threadšª¶J+„‡¼ÐÀÆÐÈÿÿÿ&­Þ~initial threadšª¶J7„‡/usr/local/lib/python2.6/site-packages}­Þ~initial threadšª¶JP„‡stat[Ñ$íA§âª¶Jtª¶J‡ª¶JÕ²J­Þ~initial threadšª¶JZ„‡¼­Þ~initial threadšª¶J„‡¼@ÀÆàÇÿÿÿ&­Þ~initial threadšª¶J™„‡/usr/local/lib/python2.6/site-packages}­Þ~initial threadšª¶J±„‡stat[Ñ$íA§âª¶Jtª¶J‡ª¶JÕ²J­Þ~initial threadšª¶J¼„‡¼ ­Þ~initial threadšª¶JÆ„‡@ÀÆ&­Þ~initial threadšª¶JÒ„‡/usr/local/lib/python2.6/site-packages­Þ~initial threadšª¶J鄇­Þ~initial threadšª¶Jô„‡½@Åÿÿÿ}­Þ~initial threadšª¶Jÿ„‡stat[Ñ$íA§âª¶Jtª¶J‡ª¶JÕ²J­Þ~initial threadšª¶J …‡½ ­Þ~initial threadšª¶J…‡\­Þ~initial threadšª¶J!…‡\­Þ~initial threadšª¶J0…‡ÀÅÿÿÿ­Þ~initial threadšª¶JG…‡(­Þ~initial threadšª¶J[…‡ÄpʨPÊ­Þ~initial threadšª¶Ji…‡Ä(­Þ~initial threadšª¶Jw…‡ÄpʨPÊ­Þ~initial threadšª¶J‚…‡Ä ­Þ~initial threadšª¶J…‡Þ­Þ~initial threadšª¶Jš…‡Þ­Þ~initial threadšª¶J¦…‡­Þ~initial threadšª¶J¿…‡­Þ~initial threadšª¶JÚ…‡¼à³ÆÐÈÿÿÿ­Þ~initial threadšª¶Jæ…‡/usr/local/lib/site-python­Þ~initial threadšª¶Jû…‡¼­Þ~initial threadšª¶J †‡¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶J†‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JJ†‡¼­Þ~initial threadšª¶JW†‡¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶Jb†‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jv†‡¼­Þ~initial threadšª¶J†‡¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶JŒ†‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J£†‡¼­Þ~initial threadšª¶J®†‡¼ÀÃÿÿÿ@Ãÿÿÿ­Þ~initial threadšª¶J¸†‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J͆‡¼­Þ~initial threadšª¶J%‡‡¼p²ÿÿÿ€¶ÿÿÿ­Þ~initial threadšª¶J1‡‡/usr/local/lib/python2.6}­Þ~initial threadšª¶JH‡‡stat[¾$íA˜`bª¶Jë²Jë²J6Ô²J­Þ~initial threadšª¶JS‡‡¼­Þ~initial threadšª¶J`‡‡¼~ݶÿÿÿ­Þ~initial threadšª¶Jk‡‡/usr/local/lib/python2.6}­Þ~initial threadšª¶J‡‡stat[¾$íA˜`bª¶Jë²Jë²J6Ô²J­Þ~initial threadšª¶JŒ‡‡¼­Þ~initial threadšª¶J˜‡‡¼Âÿÿÿ°Áÿÿÿ&­Þ~initial threadšª¶J£‡‡/usr/local/lib/python2.6/sitecustomize­Þ~initial threadšª¶J¸‡‡¼ ­Þ~initial threadšª¶Jć‡Âÿÿÿ¶)­Þ~initial threadšª¶JЇ‡/usr/local/lib/python2.6/sitecustomize.so­Þ~initial threadšª¶J懇 ­Þ~initial threadšª¶Jò‡‡Âÿÿÿ¶/­Þ~initial threadšª¶Jý‡‡/usr/local/lib/python2.6/sitecustomizemodule.so­Þ~initial threadšª¶Jˆ‡ ­Þ~initial threadšª¶Jˆ‡Âÿÿÿ¶)­Þ~initial threadšª¶J+ˆ‡/usr/local/lib/python2.6/sitecustomize.py­Þ~initial threadšª¶JAˆ‡ ­Þ~initial threadšª¶JLˆ‡Âÿÿÿ¶*­Þ~initial threadšª¶JXˆ‡/usr/local/lib/python2.6/sitecustomize.pyc­Þ~initial threadšª¶Jnˆ‡­Þ~initial threadšª¶J{ˆ‡¼p²ÿÿÿ€¶ÿÿÿ&­Þ~initial threadšª¶J‡ˆ‡/usr/local/lib/python2.6/plat-freebsd8}­Þ~initial threadšª¶JŸˆ‡stat[È$íANá(ÔµJæ²Jæ²JÔ²J­Þ~initial threadšª¶J©ˆ‡¼­Þ~initial threadšª¶J¶ˆ‡¼„"Ò°¶ÿÿÿ&­Þ~initial threadšª¶JÁˆ‡/usr/local/lib/python2.6/plat-freebsd8}­Þ~initial threadšª¶J؈‡stat[È$íANá(ÔµJæ²Jæ²JÔ²J­Þ~initial threadšª¶J㈇¼­Þ~initial threadšª¶J¼Âÿÿÿ°Áÿÿÿ4­Þ~initial threadšª¶Júˆ‡/usr/local/lib/python2.6/plat-freebsd8/sitecustomize­Þ~initial threadšª¶J‰‡¼ ­Þ~initial threadšª¶J‰‡Âÿÿÿ¶7­Þ~initial threadšª¶J(‰‡/usr/local/lib/python2.6/plat-freebsd8/sitecustomize.so­Þ~initial threadšª¶J@‰‡ ­Þ~initial threadšª¶JK‰‡Âÿÿÿ¶=­Þ~initial threadšª¶JW‰‡/usr/local/lib/python2.6/plat-freebsd8/sitecustomizemodule.so­Þ~initial threadšª¶Jn‰‡ ­Þ~initial threadšª¶Jz‰‡Âÿÿÿ¶7­Þ~initial threadšª¶J†‰‡/usr/local/lib/python2.6/plat-freebsd8/sitecustomize.py­Þ~initial threadšª¶J‰‡ ­Þ~initial threadšª¶J¨‰‡Âÿÿÿ¶8­Þ~initial threadšª¶Jµ‰‡/usr/local/lib/python2.6/plat-freebsd8/sitecustomize.pyc­Þ~initial threadšª¶J̉‡­Þ~initial threadšª¶JÙ‰‡¼p²ÿÿÿ€¶ÿÿÿ­Þ~initial threadšª¶J㉇/usr/local/lib/python2.6/lib-tk}­Þ~initial threadšª¶JЇstat[Ð$íA¥â(ÔµJå²Jå²JÕ²J­Þ~initial threadšª¶JЇ¼­Þ~initial threadšª¶JЇ¼l¼Ä°¶ÿÿÿ­Þ~initial threadšª¶J*Ї/usr/local/lib/python2.6/lib-tk}­Þ~initial threadšª¶JAЇstat[Ð$íA¥â(ÔµJå²Jå²JÕ²J­Þ~initial threadšª¶JKЇ¼­Þ~initial threadšª¶JWЇ¼Âÿÿÿ°Áÿÿÿ-­Þ~initial threadšª¶JbЇ/usr/local/lib/python2.6/lib-tk/sitecustomize­Þ~initial threadšª¶JyЇ¼ ­Þ~initial threadšª¶J„ЇÂÿÿÿ¶0­Þ~initial threadšª¶JЇ/usr/local/lib/python2.6/lib-tk/sitecustomize.so­Þ~initial threadšª¶J¨Š‡ ­Þ~initial threadšª¶J³Š‡Âÿÿÿ¶6­Þ~initial threadšª¶J¿Š‡/usr/local/lib/python2.6/lib-tk/sitecustomizemodule.so­Þ~initial threadšª¶J׊‡ ­Þ~initial threadšª¶J⊇Âÿÿÿ¶0­Þ~initial threadšª¶J/usr/local/lib/python2.6/lib-tk/sitecustomize.py­Þ~initial threadšª¶J‹‡ ­Þ~initial threadšª¶J‹‡Âÿÿÿ¶1­Þ~initial threadšª¶J‹‡/usr/local/lib/python2.6/lib-tk/sitecustomize.pyc­Þ~initial threadšª¶J4‹‡­Þ~initial threadšª¶JB‹‡¼p²ÿÿÿ€¶ÿÿÿ ­Þ~initial threadšª¶JM‹‡/usr/local/lib/python2.6/lib-old}­Þ~initial threadšª¶Jf‹‡stat[ö$íA—(ÔµJÖ²JÖ²JÖ²J­Þ~initial threadšª¶Jp‹‡¼­Þ~initial threadšª¶J|‹‡¼¾Ä°¶ÿÿÿ ­Þ~initial threadšª¶Jˆ‹‡/usr/local/lib/python2.6/lib-old}­Þ~initial threadšª¶JŸ‹‡stat[ö$íA—(ÔµJÖ²JÖ²JÖ²J­Þ~initial threadšª¶J©‹‡¼­Þ~initial threadšª¶Jµ‹‡¼Âÿÿÿ°Áÿÿÿ.­Þ~initial threadšª¶JÀ‹‡/usr/local/lib/python2.6/lib-old/sitecustomize­Þ~initial threadšª¶JÊ‹‡¼ ­Þ~initial threadšª¶Jô‹‡Âÿÿÿ¶1­Þ~initial threadšª¶JŒ‡/usr/local/lib/python2.6/lib-old/sitecustomize.so­Þ~initial threadšª¶JŒ‡ ­Þ~initial threadšª¶J$Œ‡Âÿÿÿ¶7­Þ~initial threadšª¶J/Œ‡/usr/local/lib/python2.6/lib-old/sitecustomizemodule.so­Þ~initial threadšª¶JHŒ‡ ­Þ~initial threadšª¶JSŒ‡Âÿÿÿ¶1­Þ~initial threadšª¶J^Œ‡/usr/local/lib/python2.6/lib-old/sitecustomize.py­Þ~initial threadšª¶JvŒ‡ ­Þ~initial threadšª¶JŒ‡Âÿÿÿ¶2­Þ~initial threadšª¶JŒ‡/usr/local/lib/python2.6/lib-old/sitecustomize.pyc­Þ~initial threadšª¶J¥Œ‡­Þ~initial threadšª¶J±Œ‡¼p²ÿÿÿ€¶ÿÿÿ$­Þ~initial threadšª¶J¼Œ‡/usr/local/lib/python2.6/lib-dynload}­Þ~initial threadšª¶JÔŒ‡stat[UÎíATí(ÔµJë²Jë²Jë²J­Þ~initial threadšª¶Jߌ‡¼­Þ~initial threadšª¶J댇¼TêÓ°¶ÿÿÿ$­Þ~initial threadšª¶JöŒ‡/usr/local/lib/python2.6/lib-dynload}­Þ~initial threadšª¶J ‡stat[UÎíATí(ÔµJë²Jë²Jë²J­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J$‡¼Âÿÿÿ°Áÿÿÿ2­Þ~initial threadšª¶J/‡/usr/local/lib/python2.6/lib-dynload/sitecustomize­Þ~initial threadšª¶JE‡¼ ­Þ~initial threadšª¶JP‡Âÿÿÿ¶5­Þ~initial threadšª¶Je‡/usr/local/lib/python2.6/lib-dynload/sitecustomize.so­Þ~initial threadšª¶J}‡ ­Þ~initial threadšª¶Jˆ‡Âÿÿÿ¶;­Þ~initial threadšª¶J”‡/usr/local/lib/python2.6/lib-dynload/sitecustomizemodule.so­Þ~initial threadšª¶J¬‡ ­Þ~initial threadšª¶J·‡Âÿÿÿ¶5­Þ~initial threadšª¶JÇ/usr/local/lib/python2.6/lib-dynload/sitecustomize.py­Þ~initial threadšª¶JÚ‡ ­Þ~initial threadšª¶Jå‡Âÿÿÿ¶6­Þ~initial threadšª¶Jñ‡/usr/local/lib/python2.6/lib-dynload/sitecustomize.pyc­Þ~initial threadšª¶J އ­Þ~initial threadšª¶Jއ¼p²ÿÿÿ€¶ÿÿÿ&­Þ~initial threadšª¶J އ/usr/local/lib/python2.6/site-packages}­Þ~initial threadšª¶Jfއstat[Ñ$íA§âšª¶Jtª¶J‡ª¶JÕ²J­Þ~initial threadšª¶Jqއ¼­Þ~initial threadšª¶J~އ¼4lѰ¶ÿÿÿ&­Þ~initial threadšª¶J‰Ž‡/usr/local/lib/python2.6/site-packages}­Þ~initial threadšª¶J Ž‡stat[Ñ$íA§âšª¶Jtª¶J‡ª¶JÕ²J­Þ~initial threadšª¶J«Ž‡¼­Þ~initial threadšª¶J·Ž‡¼Âÿÿÿ°Áÿÿÿ4­Þ~initial threadšª¶JÌŽ‡/usr/local/lib/python2.6/site-packages/sitecustomize­Þ~initial threadšª¶J㎇¼ ­Þ~initial threadšª¶JÂÿÿÿ¶7­Þ~initial threadšª¶Júއ/usr/local/lib/python2.6/site-packages/sitecustomize.so­Þ~initial threadšª¶J‡ ­Þ~initial threadšª¶J‡Âÿÿÿ¶=­Þ~initial threadšª¶J)‡/usr/local/lib/python2.6/site-packages/sitecustomizemodule.so­Þ~initial threadšª¶JA‡ ­Þ~initial threadšª¶JL‡Âÿÿÿ¶7­Þ~initial threadšª¶JX‡/usr/local/lib/python2.6/site-packages/sitecustomize.py­Þ~initial threadšª¶Jp‡ ­Þ~initial threadšª¶J{‡Âÿÿÿ¶8­Þ~initial threadšª¶J‡‡/usr/local/lib/python2.6/site-packages/sitecustomize.pyc­Þ~initial threadšª¶Jž‡­Þ~initial threadšª¶J¶‡¼Âÿÿÿ°Áÿÿÿ&­Þ~initial threadšª¶J‡/usr/local/lib/python2.6/usercustomize­Þ~initial threadšª¶J؇¼ ­Þ~initial threadšª¶Jã‡Âÿÿÿ¶)­Þ~initial threadšª¶Jþ‡/usr/local/lib/python2.6/usercustomize.so­Þ~initial threadšª¶J‡ ­Þ~initial threadšª¶J"‡Âÿÿÿ¶/­Þ~initial threadšª¶J.‡/usr/local/lib/python2.6/usercustomizemodule.so­Þ~initial threadšª¶JD‡ ­Þ~initial threadšª¶JO‡Âÿÿÿ¶)­Þ~initial threadšª¶J[‡/usr/local/lib/python2.6/usercustomize.py­Þ~initial threadšª¶Jq‡ ­Þ~initial threadšª¶J|‡Âÿÿÿ¶*­Þ~initial threadšª¶Jˆ‡/usr/local/lib/python2.6/usercustomize.pyc­Þ~initial threadšª¶JŸ‡­Þ~initial threadšª¶Jª‡¼Âÿÿÿ°Áÿÿÿ4­Þ~initial threadšª¶Jµ‡/usr/local/lib/python2.6/plat-freebsd8/usercustomize­Þ~initial threadšª¶J̇¼ ­Þ~initial threadšª¶JׇÂÿÿÿ¶7­Þ~initial threadšª¶Jã‡/usr/local/lib/python2.6/plat-freebsd8/usercustomize.so­Þ~initial threadšª¶Jú‡ ­Þ~initial threadšª¶J‘‡Âÿÿÿ¶=­Þ~initial threadšª¶J‘‡/usr/local/lib/python2.6/plat-freebsd8/usercustomizemodule.so­Þ~initial threadšª¶J)‘‡ ­Þ~initial threadšª¶J4‘‡Âÿÿÿ¶7­Þ~initial threadšª¶J@‘‡/usr/local/lib/python2.6/plat-freebsd8/usercustomize.py­Þ~initial threadšª¶JW‘‡ ­Þ~initial threadšª¶Jb‘‡Âÿÿÿ¶8­Þ~initial threadšª¶Jn‘‡/usr/local/lib/python2.6/plat-freebsd8/usercustomize.pyc­Þ~initial threadšª¶J†‘‡­Þ~initial threadšª¶J‘‘‡¼Âÿÿÿ°Áÿÿÿ-­Þ~initial threadšª¶Jœ‘‡/usr/local/lib/python2.6/lib-tk/usercustomize­Þ~initial threadšª¶J³‘‡¼ ­Þ~initial threadšª¶J¾‘‡Âÿÿÿ¶0­Þ~initial threadšª¶JÊ‘‡/usr/local/lib/python2.6/lib-tk/usercustomize.so­Þ~initial threadšª¶J⑇ ­Þ~initial threadšª¶J푇Âÿÿÿ¶6­Þ~initial threadšª¶Jø‘‡/usr/local/lib/python2.6/lib-tk/usercustomizemodule.so­Þ~initial threadšª¶J’‡ ­Þ~initial threadšª¶J’‡Âÿÿÿ¶0­Þ~initial threadšª¶J'’‡/usr/local/lib/python2.6/lib-tk/usercustomize.py­Þ~initial threadšª¶J?’‡ ­Þ~initial threadšª¶JJ’‡Âÿÿÿ¶1­Þ~initial threadšª¶JU’‡/usr/local/lib/python2.6/lib-tk/usercustomize.pyc­Þ~initial threadšª¶Jm’‡­Þ~initial threadšª¶Jx’‡¼Âÿÿÿ°Áÿÿÿ.­Þ~initial threadšª¶Jƒ’‡/usr/local/lib/python2.6/lib-old/usercustomize­Þ~initial threadšª¶J𒇼 ­Þ~initial threadšª¶J¥’‡Âÿÿÿ¶1­Þ~initial threadšª¶J±’‡/usr/local/lib/python2.6/lib-old/usercustomize.so­Þ~initial threadšª¶JÈ’‡ ­Þ~initial threadšª¶JÓ’‡Âÿÿÿ¶7­Þ~initial threadšª¶Jß’‡/usr/local/lib/python2.6/lib-old/usercustomizemodule.so­Þ~initial threadšª¶J÷’‡ ­Þ~initial threadšª¶J“‡Âÿÿÿ¶1­Þ~initial threadšª¶J“‡/usr/local/lib/python2.6/lib-old/usercustomize.py­Þ~initial threadšª¶J%“‡ ­Þ~initial threadšª¶J0“‡Âÿÿÿ¶2­Þ~initial threadšª¶J<“‡/usr/local/lib/python2.6/lib-old/usercustomize.pyc­Þ~initial threadšª¶JS“‡­Þ~initial threadšª¶J_“‡¼Âÿÿÿ°Áÿÿÿ2­Þ~initial threadšª¶Ji“‡/usr/local/lib/python2.6/lib-dynload/usercustomize­Þ~initial threadšª¶JŠ“‡¼ ­Þ~initial threadšª¶J•“‡Âÿÿÿ¶5­Þ~initial threadšª¶J¡“‡/usr/local/lib/python2.6/lib-dynload/usercustomize.so­Þ~initial threadšª¶J¹“‡ ­Þ~initial threadšª¶JÄ“‡Âÿÿÿ¶;­Þ~initial threadšª¶JГ‡/usr/local/lib/python2.6/lib-dynload/usercustomizemodule.so­Þ~initial threadšª¶J瓇 ­Þ~initial threadšª¶Jò“‡Âÿÿÿ¶5­Þ~initial threadšª¶Jþ“‡/usr/local/lib/python2.6/lib-dynload/usercustomize.py­Þ~initial threadšª¶J”‡ ­Þ~initial threadšª¶J!”‡Âÿÿÿ¶6­Þ~initial threadšª¶J-”‡/usr/local/lib/python2.6/lib-dynload/usercustomize.pyc­Þ~initial threadšª¶JD”‡­Þ~initial threadšª¶JP”‡¼Âÿÿÿ°Áÿÿÿ4­Þ~initial threadšª¶J[”‡/usr/local/lib/python2.6/site-packages/usercustomize­Þ~initial threadšª¶Jq”‡¼ ­Þ~initial threadšª¶J|”‡Âÿÿÿ¶7­Þ~initial threadšª¶Jˆ”‡/usr/local/lib/python2.6/site-packages/usercustomize.so­Þ~initial threadšª¶J ”‡ ­Þ~initial threadšª¶J«”‡Âÿÿÿ¶=­Þ~initial threadšª¶J·”‡/usr/local/lib/python2.6/site-packages/usercustomizemodule.so­Þ~initial threadšª¶JΔ‡ ­Þ~initial threadšª¶JÚ”‡Âÿÿÿ¶7­Þ~initial threadšª¶J唇/usr/local/lib/python2.6/site-packages/usercustomize.py­Þ~initial threadšª¶Jý”‡ ­Þ~initial threadšª¶J•‡Âÿÿÿ¶8­Þ~initial threadšª¶J•‡/usr/local/lib/python2.6/site-packages/usercustomize.pyc­Þ~initial threadšª¶J+•‡­Þ~initial threadšª¶JC•‡­Þ~initial threadšª¶JQ•‡­Þ~initial threadšª¶J•‡¼`Üÿÿÿ€Ûÿÿÿ"­Þ~initial threadšª¶J•‡/usr/local/lib/python2.6/encodings}­Þ~initial threadšª¶JÄ•‡stat[Ô$íA`Y(ÔµJå²Jå²J Õ²J­Þ~initial threadšª¶JÏ•‡¼­Þ~initial threadšª¶JÙ•‡¼`Üÿÿÿ Óÿÿÿ.­Þ~initial threadšª¶J䕇/usr/local/lib/python2.6/encodings/__init__.py}­Þ~initial threadšª¶Jÿ•‡stat[!($=êñ²JÚ²JÚ²J Ú²J­Þ~initial threadšª¶J –‡¼­Þ~initial threadšª¶J–‡¼Øÿÿÿ0×ÿÿÿ+­Þ~initial threadšª¶J$–‡/usr/local/lib/python2.6/encodings/__init__­Þ~initial threadšª¶J;–‡¼ ­Þ~initial threadšª¶JF–‡Øÿÿÿ¶.­Þ~initial threadšª¶JR–‡/usr/local/lib/python2.6/encodings/__init__.so­Þ~initial threadšª¶Jj–‡ ­Þ~initial threadšª¶Ju–‡Øÿÿÿ¶4­Þ~initial threadšª¶J–‡/usr/local/lib/python2.6/encodings/__init__module.so­Þ~initial threadšª¶J™–‡ ­Þ~initial threadšª¶J¤–‡Øÿÿÿ¶.­Þ~initial threadšª¶J°–‡/usr/local/lib/python2.6/encodings/__init__.py­Þ~initial threadšª¶JÉ–‡­Þ~initial threadšª¶JÔ–‡½ ×ÿÿÿ}­Þ~initial threadšª¶Jà–‡stat[!($=êñ²JÚ²JÚ²J Ú²J­Þ~initial threadšª¶Jê–‡½ ­Þ~initial threadšª¶Jõ–‡Óÿÿÿ¶/­Þ~initial threadšª¶J—‡/usr/local/lib/python2.6/encodings/__init__.pyc­Þ~initial threadšª¶J—‡­Þ~initial threadšª¶J$—‡½€Ñÿÿÿ}­Þ~initial threadšª¶J0—‡stat[¥*$å4ª¶Jß²Jß²JP Þ²J­Þ~initial threadšª¶J:—‡½ ­Þ~initial threadšª¶JF—‡PÊ­Þ~initial threadšª¶J`—‡Ñò Ú²Jc@sŽdZddkZddklZddkZhZdZdgZdZeiZ de e fd„ƒYZ d „Z d „ZeieƒdS( s, Standard "encodings" Package Standard Python encoding modules are stored in this package directory. Codec modules must have names corresponding to normalized encoding names as defined in the normalize_encoding() function below, e.g. 'utf-8' must be implemented by the module 'utf_8.py'. Each codec module must export the following interface: * getregentry() -> codecs.CodecInfo object The getregentry() API must a CodecInfo object with encoder, decoder, incrementalencoder, incrementaldecoder, streamwriter and streamreader atttributes which adhere to the Python Codec Interface Standard. In addition, a module may optionally also define the following APIs which are then used by the package's codec search function: * getaliases() -> sequence of encoding name strings to use as aliases Alias names returned by getaliases() must be normalized encoding names as defined by normalize_encoding(). Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. iÿÿÿÿN(taliasess --unknown--t*s . 0123456789 ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz tCodecRegistryErrorcBseZRS((t__name__t __module__(((s./usr/local/lib/python2.6/encodings/__init__.pyR.scCsOttdƒo#t|tƒo|idƒ}ndi|itƒiƒƒS(s´ Normalize an encoding name. Normalization works as follows: all non-alphanumeric characters except the dot used for Python package names are collapsed and replaced with a single underscore, e.g. ' -;#' becomes '_'. Leading and trailing underscores are removed. Note that encoding names should be ASCII only; if they do use non-ASCII characters, these must be Latin-1 compatible. tunicodeslatin-1t_( thasattrt __builtin__t isinstanceRtencodetjoint translatet_norm_encoding_maptsplit(tencoding((s./usr/local/lib/python2.6/encodings/__init__.pytnormalize_encoding1s c CsPti|tƒ}|tj o|St|ƒ}ti|ƒpti|iddƒƒ}|dj o||g}n |g}xg|D]Y}| p d|joqˆny td|dtddƒ}Wnt j oqˆXPqˆWd}y |i }Wnt j o d}nX|djodt|s      V­Þ~initial threadšª¶Jà—‡P ­Þ~initial threadšª¶Jê—‡PÊ­Þ~initial threadšª¶Jö—‡­Þ~initial threadšª¶J˜‡­Þ~initial threadšª¶J#˜‡­Þ~initial threadšª¶J4˜‡­Þ~initial threadšª¶JQ˜‡¼µÿÿÿ ¹ÿÿÿ"­Þ~initial threadšª¶J]˜‡/usr/local/lib/python2.6/encodings}­Þ~initial threadšª¶Jv˜‡stat[Ô$íA`Y(ÔµJå²Jå²J Õ²J­Þ~initial threadšª¶J˜‡¼­Þ~initial threadšª¶JŽ˜‡¼ôÃP¹ÿÿÿ"­Þ~initial threadšª¶J™˜‡/usr/local/lib/python2.6/encodings}­Þ~initial threadšª¶J°˜‡stat[Ô$íA`Y(ÔµJå²Jå²J Õ²J­Þ~initial threadšª¶J»˜‡¼­Þ~initial threadšª¶Jǘ‡¼0ÅÿÿÿPÄÿÿÿ)­Þ~initial threadšª¶Jј‡/usr/local/lib/python2.6/encodings/codecs­Þ~initial threadšª¶J阇¼ ­Þ~initial threadšª¶Jô˜‡0Åÿÿÿ¶,­Þ~initial threadšª¶J™‡/usr/local/lib/python2.6/encodings/codecs.so­Þ~initial threadšª¶J™‡ ­Þ~initial threadšª¶J#™‡0Åÿÿÿ¶2­Þ~initial threadšª¶J/™‡/usr/local/lib/python2.6/encodings/codecsmodule.so­Þ~initial threadšª¶JF™‡ ­Þ~initial threadšª¶JR™‡0Åÿÿÿ¶,­Þ~initial threadšª¶J]™‡/usr/local/lib/python2.6/encodings/codecs.py­Þ~initial threadšª¶Ju™‡ ­Þ~initial threadšª¶J€™‡0Åÿÿÿ¶-­Þ~initial threadšª¶JŒ™‡/usr/local/lib/python2.6/encodings/codecs.pyc­Þ~initial threadšª¶J¤™‡­Þ~initial threadšª¶JÄ™‡¼0ÅÿÿÿPÄÿÿÿ­Þ~initial threadšª¶JÑ™‡/usr/local/lib/python2.6/codecs­Þ~initial threadšª¶J癇¼ ­Þ~initial threadšª¶Jó™‡0Åÿÿÿ¶"­Þ~initial threadšª¶Jÿ™‡/usr/local/lib/python2.6/codecs.so­Þ~initial threadšª¶Jš‡ ­Þ~initial threadšª¶J š‡0Åÿÿÿ¶(­Þ~initial threadšª¶J,š‡/usr/local/lib/python2.6/codecsmodule.so­Þ~initial threadšª¶JBš‡ ­Þ~initial threadšª¶JMš‡0Åÿÿÿ¶"­Þ~initial threadšª¶JYš‡/usr/local/lib/python2.6/codecs.py­Þ~initial threadšª¶Jpš‡­Þ~initial threadšª¶J{š‡½@Äÿÿÿ}­Þ~initial threadšª¶J‡š‡stat["%$ ï²JÖ²JÖ²J“‡DÖ²J­Þ~initial threadšª¶J‘š‡½ ­Þ~initial threadšª¶Jœš‡0Àÿÿÿ¶#­Þ~initial threadšª¶J¨š‡/usr/local/lib/python2.6/codecs.pyc­Þ~initial threadšª¶JÀš‡­Þ~initial threadšª¶JËš‡½ ¾ÿÿÿ}­Þ~initial threadšª¶JÖš‡stat[¦*$è4ª¶Jß²Jß²JtŽHÞ²J­Þ~initial threadšª¶Jàš‡½ ­Þ~initial threadšª¶J욇PÊ­Þ~initial threadšª¶J›‡Ñò Ö²Jc@sAdZddkZddkZyddkTWn%ej oZedeƒ‚nXddddd d d d d dddddddddddddddgZdZdZ Z dZ Z d Z d!Zeid"joe ZZe Zne ZZeZe Ze Ze ZeZd#efd$„ƒYZd%dNd&„ƒYZd'efd(„ƒYZd)efd*„ƒYZd+efd,„ƒYZd-efd.„ƒYZd/efd0„ƒYZd1efd2„ƒYZ d3dOd4„ƒYZ!d5dPd6„ƒYZ"d7dd8d9d:„Z$dd8d;„Z%d<„Z&d=„Z'd>„Z(d?„Z)d@„Z*dA„Z+d8dB„Z,d8dC„Z-dD„Z.dE„Z/y@e0d8ƒZ1e0dFƒZ2e0dGƒZ3e0dHƒZ4e0dIƒZ5Wn1e6j o%dZ1dZ2dZ3dZ4dZ5nXdJZ7e7oddk8Z8ne9dKjo4e%ei:dLdMƒe_:e%ei;dMdLƒe_;ndS(Qsž codecs -- Python Codec Registry, API and helpers. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. iÿÿÿÿN(t*s%Failed to load the builtin codecs: %stregistertlookuptopent EncodedFiletBOMtBOM_BEtBOM_LEtBOM32_BEtBOM32_LEtBOM64_BEtBOM64_LEtBOM_UTF8t BOM_UTF16t BOM_UTF16_LEt BOM_UTF16_BEt BOM_UTF32t BOM_UTF32_LEt BOM_UTF32_BEt strict_errorst ignore_errorstreplace_errorstxmlcharrefreplace_errorstregister_errort lookup_errorssÿþsþÿsÿþtþÿtlittlet CodecInfocBs)eZdddddd„Zd„ZRS(c Csati|||||fƒ}||_||_||_||_||_||_||_|S(N( ttuplet__new__tnametencodetdecodetincrementalencodertincrementaldecodert streamwritert streamreader( tclsRR R$R#R!R"Rtself((s"/usr/local/lib/python2.6/codecs.pyRMs       cCs)d|ii|ii|it|ƒfS(Ns&<%s.%s object for encoding %s at 0x%x>(t __class__t __module__t__name__Rtid(R&((s"/usr/local/lib/python2.6/codecs.pyt__repr__YsN(R)R(tNoneRR+(((s"/usr/local/lib/python2.6/codecs.pyRKs tCodeccBs&eZdZdd„Zdd„ZRS(s­ Defines the interface for stateless encoders/decoders. The .encode()/.decode() methods may use different error handling schemes by providing the errors argument. These string values are predefined: 'strict' - raise a ValueError error (or a subclass) 'ignore' - ignore the character and continue with the next 'replace' - replace with a suitable replacement character; Python will use the official U+FFFD REPLACEMENT CHARACTER for the builtin Unicode codecs on decoding and '?' on encoding. 'xmlcharrefreplace' - Replace with the appropriate XML character reference (only for encoding). 'backslashreplace' - Replace with backslashed escape sequences (only for encoding). The set of allowed values can be extended via register_error. tstrictcCs t‚dS(s+ Encodes the object input and returns a tuple (output object, length consumed). errors defines the error handling to apply. It defaults to 'strict' handling. The method may not store state in the Codec instance. Use StreamCodec for codecs which have to keep state in order to make encoding/decoding efficient. The encoder must be able to handle zero length input and return an empty object of the output object type in this situation. N(tNotImplementedError(R&tinputterrors((s"/usr/local/lib/python2.6/codecs.pyRrs­Þ~initial threadšª¶J›‡­Þ~initial threadšª¶J›‡½Àÿÿÿ}­Þ~initial threadšª¶J'›‡stat[¦*$è4šª¶Jß²Jß²JtŽHÞ²J­Þ~initial threadšª¶J1›‡½ ­Þ~initial threadšª¶Jr›‡PÊ­Þ~initial threadšª¶J‰›‡cCs t‚dS(sú Decodes the object input and returns a tuple (output object, length consumed). input must be an object which provides the bf_getreadbuf buffer slot. Python strings, buffer objects and memory mapped files are examples of objects providing this slot. errors defines the error handling to apply. It defaults to 'strict' handling. The method may not store state in the Codec instance. Use StreamCodec for codecs which have to keep state in order to make encoding/decoding efficient. The decoder must be able to handle zero length input and return an empty object of the output object type in this situation. N(R/(R&R0R1((s"/usr/local/lib/python2.6/codecs.pyR …s(R)R(t__doc__RR (((s"/usr/local/lib/python2.6/codecs.pyR-\s tIncrementalEncodercBsAeZdZdd„Zed„Zd„Zd„Zd„ZRS(sè An IncrementalEncoder encodes an input in multiple steps. The input can be passed piece by piece to the encode() method. The IncrementalEncoder remembers the state of the Encoding process between calls to encode(). R.cCs||_d|_dS(sô Creates an IncrementalEncoder instance. The IncrementalEncoder may use different error handling schemes by providing the errors keyword argument. See the module docstring for a list of possible values. tN(R1tbuffer(R&R1((s"/usr/local/lib/python2.6/codecs.pyt__init__¢s cCs t‚dS(sA Encodes input and returns the resulting object. N(R/(R&R0tfinal((s"/usr/local/lib/python2.6/codecs.pyR­scCsdS(s: Resets the encoder to the initial state. N((R&((s"/usr/local/lib/python2.6/codecs.pytreset³scCsdS(s: Return the current state of the encoder. i((R&((s"/usr/local/lib/python2.6/codecs.pytgetstate¸scCsdS(sl Set the current state of the encoder. state must have been returned by getstate(). N((R&tstate((s"/usr/local/lib/python2.6/codecs.pytsetstate¾s( R)R(R2R6tFalseRR8R9R;(((s"/usr/local/lib/python2.6/codecs.pyR3œs    tBufferedIncrementalEncodercBsJeZdZdd„Zd„Zed„Zd„Zd„Zd„Z RS(sÀ This subclass of IncrementalEncoder can be used as the baseclass for an incremental encoder if the encoder must keep some of the output in a buffer between calls to encode(). R.cCsti||ƒd|_dS(NR4(R3R6R5(R&R1((s"/usr/local/lib/python2.6/codecs.pyR6ÊscCs t‚dS(N(R/(R&R0R1R7((s"/usr/local/lib/python2.6/codecs.pyt_buffer_encodeÎscCs<|i|}|i||i|ƒ\}}|||_|S(N(R5R>R1(R&R0R7tdatatresulttconsumed((s"/usr/local/lib/python2.6/codecs.pyRÓs  cCsti|ƒd|_dS(NR4(R3R8R5(R&((s"/usr/local/lib/python2.6/codecs.pyR8Ûs cCs|ipdS(Ni(R5(R&((s"/usr/local/lib/python2.6/codecs.pyR9ßscCs|pd|_dS(NR4(R5(R&R:((s"/usr/local/lib/python2.6/codecs.pyR;âs( R)R(R2R6R>R<RR8­Þ~initial threadšª¶J•›‡ ­Þ~initial threadšª¶J ›‡PÊ­Þ~initial threadšª¶Jµ›‡R9R;(((s"/usr/local/lib/python2.6/codecs.pyR=Äs     tIncrementalDecodercBsAeZdZdd„Zed„Zd„Zd„Zd„ZRS(sè An IncrementalDecoder decodes an input in multiple steps. The input can be passed piece by piece to the decode() method. The IncrementalDecoder remembers the state of the decoding process between calls to decode(). R.cCs ||_dS(só Creates a IncrementalDecoder instance. The IncrementalDecoder may use different error handling schemes by providing the errors keyword argument. See the module docstring for a list of possible values. N(R1(R&R1((s"/usr/local/lib/python2.6/codecs.pyR6ëscCs t‚dS(sA Decodes input and returns the resulting object. N(R/(R&R0R7((s"/usr/local/lib/python2.6/codecs.pyR õscCsdS(s: Resets the decoder to the initial state. N((R&((s"/usr/local/lib/python2.6/codecs.pyR8ûscCsdS(s  Return the current state of the decoder. This must be a (buffered_input, additional_state_info) tuple. buffered_input must be a bytes object containing bytes that were passed to decode() that have not yet been converted. additional_state_info must be a non-negative integer representing the state of the decoder WITHOUT yet having processed the contents of buffered_input. In the initial state and after reset(), getstate() must return (b"", 0). R4i(R4i((R&((s"/usr/local/lib/python2.6/codecs.pyR9s cCsdS(s¶ Set the current state of the decoder. state must have been returned by getstate(). The effect of setstate((b"", 0)) must be equivalent to reset(). N((R&R:((s"/usr/local/lib/python2.6/codecs.pyR;s( R)R(R2R6R<R R8R9R;(((s"/usr/local/lib/python2.6/codecs.pyRBås    tBufferedIncrementalDecodercBsJeZdZdd„Zd„Zed„Zd„Zd„Zd„Z RS(s® This subclass of IncrementalDecoder can be used as the baseclass for an incremental decoder if the decoder must be able to handle incomplete byte sequences. R.cCsti||ƒd|_dS(NR4(RBR6R5(R&R1((s"/usr/local/lib/python2.6/codecs.pyR6scCs t‚dS(N(R/(R&R0R1R7((s"/usr/local/lib/python2.6/codecs.pyt_buffer_decode scCs<|i|}|i||i|ƒ\}}|||_|S(N(R5RDR1(R&R0R7R?R@RA((s"/usr/local/lib/python2.6/codecs.pyR %s  cCsti|ƒd|_dS(NR4(RBR8R5(R&((s"/usr/local/lib/python2.6/codecs.pyR8-s cCs |idfS(Ni(R5(R&((s"/usr/local/lib/python2.6/codecs.pyR91scCs|d|_dS(Ni(R5(R&R:((s"/usr/local/lib/python2.6/codecs.pyR;5s( R)R(R2R6RDR<R R8R9R;(((s"/usr/local/lib/python2.6/codecs.pyRCs     t StreamWritercBsMeZdd„Zd„Zd„Zd„Zed„Zd„Zd„Z RS(R.cCs||_||_dS(s[ Creates a StreamWriter instance. stream must be a file-like object open for writing (binary) data. The StreamWriter may use different error handling schemes ­Þ~initial threadšª¶J웇 ­Þ~initial threadšª¶Jø›‡PÊ­Þ~initial threadšª¶J œ‡by providing the errors keyword argument. These parameters are predefined: 'strict' - raise a ValueError (or a subclass) 'ignore' - ignore the character and continue with the next 'replace'- replace with a suitable replacement character 'xmlcharrefreplace' - Replace with the appropriate XML character reference. 'backslashreplace' - Replace with backslashed escape sequences (only for encoding). The set of allowed parameter values can be extended via register_error. N(tstreamR1(R&RFR1((s"/usr/local/lib/python2.6/codecs.pyR6Bs cCs/|i||iƒ\}}|ii|ƒdS(s> Writes the object's contents encoded to self.stream. N(RR1RFtwrite(R&tobjectR?RA((s"/usr/local/lib/python2.6/codecs.pyRG[scCs|idi|ƒƒdS(s[ Writes the concatenated list of strings to the stream using .write(). R4N(RGtjoin(R&tlist((s"/usr/local/lib/python2.6/codecs.pyt writelinesbscCsdS(s5 Flushes and resets the codec buffers used for keeping state. Calling this method should ensure that the data on the output is put into a clean state, that allows appending of new fresh data without having to rescan the whole stream to recover state. N((R&((s"/usr/local/lib/python2.6/codecs.pyR8is cCs||i|ƒS(s? Inherit all other methods from the underlying stream. (RF(R&Rtgetattr((s"/usr/local/lib/python2.6/codecs.pyt __getattr__uscCs|S(N((R&((s"/usr/local/lib/python2.6/codecs.pyt __enter__|scCs|iiƒdS(N(RFtclose(R&ttypetvaluettb((s"/usr/local/lib/python2.6/codecs.pyt__exit__s( R)R(R6RGRKR8RLRMRNRS(((s"/usr/local/lib/python2.6/codecs.pyRE@s     t StreamReadercBs•eZdd„Zdd„Zdded„Zded„Zded„Z d„Z dd „Z d „Z d „Z ed „Zd „Zd„ZRS(R.cCs1||_||_d|_d|_d|_dS(s[ Creates a StreamReader instance. stream must be a file-like object open for reading (binary) data. The StreamReader may use different error handling schemes by providing the errors keyword argument. These parameters are predefined: 'strict' - raise a ValueError (or a subclass) 'ignore' - ignore the character and continue with the next 'replace'- replace with a suitable replacement character; The set of allowed parameter values can be extended via register_error. R4N(RFR1t bytebuffert charbufferR,t linebuffer(R&RFR1((s"/usr/local/lib/python2.6/codecs.pyR6†s     cCs t‚dS(N(R/(R&R0R1((s"/usr/local/lib/python2.6/codecs.pyR  siÿÿÿÿc CsÝ|io"di|iƒ|_d|_nxjtob|djo?|djo|ioPq~qt|iƒ|joPqnt|iƒ|joPn|djo|iiƒ}n|ii|ƒ}|i|}y|i ||i ƒ\}}Wnnt j ob}|oO|i ||i |i ƒ\}}|i tƒ} t| ƒdjo‚qgql‚nX|||_|i|7_|pPq/q/W|djo|i} d|_n|i| } |i||_| S(s Decodes data from the ­Þ~initial threadšª¶Jœ‡ ­Þ~initial threadšª¶J$œ‡PÊ­Þ~initial threadšª¶J4œ‡stream self.stream and returns the resulting object. chars indicates the number of characters to read from the stream. read() will never return more than chars characters, but it might return less, if there are not enough characters available. size indicates the approximate maximum number of bytes to read from the stream for decoding purposes. The decoder can modify this setting as appropriate. The default value -1 indicates to read and decode as much as possible. size is intended to prevent having to decode huge files in one step. If firstline is true, and a UnicodeDecodeError happens after the first line terminator in the input only the first line will be returned, the rest of the input will be kept until the next call to read(). The method should use a greedy read strategy meaning that it should read as much data as is allowed within the definition of the encoding and the given size, e.g. if optional encoding endings or state markers are available on the stream, these should be read too. R4iiN(RWRIRVR,tTruetlenRFtreadRUR R1tUnicodeDecodeErrortstartt splitlines( R&tsizetcharst firstlinetnewdataR?tnewcharst decodedbytestexctlinesR@((s"/usr/local/lib/python2.6/codecs.pyRZ£sH         "       c Csj|iom|id}|id=t|iƒdjo|id|_d |_n|p|itƒd}n|S|pd}d}xÙtoÑ|i|dtƒ}|o4|idƒo ||iddddƒ7}qän||7}|itƒ}|ot|ƒdjo„|d}|d=t|ƒdjo)|d c|i7<||_d |_n|d|i|_|p|itƒd}nPn|d}|ditƒd}||jo9di |dƒ|i|_|o |}n|}Pqn| p |d j o+|o| o|itƒd}nPn|d jo|d 9}qqW|S( s± Read one line from the input stream and return the decoded data. size, if given, is passed as size argument to the read() method. iiiHR4R`s R^R_iÿÿÿÿi@iN( RWRYRVR,R]R<RXRZtendswithRI( R&R^tkeependstlinetreadsizeR?Ret line0withendtline0withoutend((s"/usr/local/lib/python2.6/codecs.pytreadlineòs\     $         cCs|iƒ}|i|ƒS(sZ Read all lines available on the input stream and return them as list of lines. Line breaks are implemented using the codec's decoder method and are included in the list entries. sizehint, if given, is ignored since there is no efficient way to finding the true end-of-line. (RZR](R&tsizehintRgR?((s"/usr/local/lib/python2.6/codecs.pyt readlines;s cCsd|_d|_d|_dS(sã Resets the codec buffers used for keeping state. Note that no stream repositioning should take place. This method is primarily intended to be able to recover from decoding errors. R4uN(RURVR,RW(R&((s"/usr/local/lib/python2.6/codecs.pyR8Js  icCs!|iƒ|ii||ƒdS(sp Set the input stream's current position. Resets the codec buffers used for keeping state. N(R8RFtseek(R&toffsettwhence((s"/usr/local/lib/python2.6/codecs.pyRoWs c­Þ~initial threadšª¶J?œ‡ ­Þ~initial threadšª¶JJœ‡PÊ­Þ~initial threadšª¶JYœ‡Cs"|iƒ}|o|St‚dS(s4 Return the next decoded line from the input stream.N(Rlt StopIteration(R&Rh((s"/usr/local/lib/python2.6/codecs.pytnext_s cCs|S(N((R&((s"/usr/local/lib/python2.6/codecs.pyt__iter__gscCs||i|ƒS(s? Inherit all other methods from the underlying stream. (RF(R&RRL((s"/usr/local/lib/python2.6/codecs.pyRMjscCs|S(N((R&((s"/usr/local/lib/python2.6/codecs.pyRNqscCs|iiƒdS(N(RFRO(R&RPRQRR((s"/usr/local/lib/python2.6/codecs.pyRStsN(R)R(R6R R<RZR,RXRlRnR8RoRsRtRLRMRNRS(((s"/usr/local/lib/python2.6/codecs.pyRT„s  OI     tStreamReaderWritercBseZdZdZdd„Zdd„Zdd„Zdd„Zd„Z d „Z d „Z d „Z d „Z ed „Zd„Zd„ZRS(s StreamReaderWriter instances allow wrapping streams which work in both read and write modes. The design is such that one can use the factory functions returned by the codec.lookup() function to construct the instance. tunknownR.cCs:||_|||ƒ|_|||ƒ|_||_dS(sR Creates a StreamReaderWriter instance. stream must be a Stream-like object. Reader, Writer must be factory functions or classes providing the StreamReader, StreamWriter interface resp. Error handling is done in the same way as defined for the StreamWriter/Readers. N(RFtreadertwriterR1(R&RFtReadertWriterR1((s"/usr/local/lib/python2.6/codecs.pyR6†s iÿÿÿÿcCs|ii|ƒS(N(RwRZ(R&R^((s"/usr/local/lib/python2.6/codecs.pyRZ˜scCs|ii|ƒS(N(RwRl(R&R^((s"/usr/local/lib/python2.6/codecs.pyRlœscCs|ii|ƒS(N(RwRn(R&Rm((s"/usr/local/lib/python2.6/codecs.pyRn scCs |iiƒS(s4 Return the next decoded line from the input stream.(RwRs(R&((s"/usr/local/lib/python2.6/codecs.pyRs¤scCs|S(N((R&((s"/usr/local/lib/python2.6/codecs.pyRt©scCs|ii|ƒS(N(RxRG(R&R?((s"/usr/local/lib/python2.6/codecs.pyRG¬scCs|ii|ƒS(N(RxRK(R&RJ((s"/usr/local/lib/python2.6/codecs.pyRK°scCs|iiƒ|iiƒdS(N(RwR8Rx(R&((s"/usr/local/lib/python2.6/codecs.pyR8´s cCs||i|ƒS(s? Inherit all other methods from the underlying stream. (RF(R&RRL((s"/usr/local/lib/python2.6/codecs.pyRM¹scCs|S(N((R&((s"/usr/local/lib/python2.6/codecs.pyRNÂscCs|iiƒdS(N(RFRO(R&RPRQRR((s"/usr/local/lib/python2.6/codecs.pyRSÅsN(R)R(R2tencodingR6RZR,RlRnRsRtRGRKR8RLRMRNRS(((s"/usr/local/lib/python2.6/codecs.pyRuys            t StreamRecodercBs•eZdZdZdZdd„Zdd„Zdd„Zdd„Z d„Z d „Z d „Z d „Z d „Zed „Zd„Zd„ZRS(sE StreamRecoder inst­Þ~initial threadšª¶Jeœ‡ ­Þ~initial threadšª¶Jpœ‡PÊ­Þ~initial threadšª¶Jœ‡ances provide a frontend - backend view of encoding data. They use the complete set of APIs returned by the codecs.lookup() function to implement their task. Data written to the stream is first decoded into an intermediate format (which is dependent on the given codec combination) and then written to the stream using an instance of the provided Writer class. In the other direction, data is read from the stream using a Reader instance and then return encoded data to the caller. RvR.cCsL||_||_||_|||ƒ|_|||ƒ|_||_dS(sº Creates a StreamRecoder instance which implements a two-way conversion: encode and decode work on the frontend (the input to .read() and output of .write()) while Reader and Writer work on the backend (reading and writing to the stream). You can use these objects to do transparent direct recodings from e.g. latin-1 to utf-8 and back. stream must be a file-like object. encode, decode must adhere to the Codec interface, Reader, Writer must be factory functions or classes providing the StreamReader, StreamWriter interface resp. encode and decode are needed for the frontend translation, Reader and Writer for the backend translation. Unicode is used as intermediate encoding. Error handling is done in the same way as defined for the StreamWriter/Readers. N(RFRR RwRxR1(R&RFRR RyRzR1((s"/usr/local/lib/python2.6/codecs.pyR6ßs    iÿÿÿÿcCs1|ii|ƒ}|i||iƒ\}}|S(N(RwRZRR1(R&R^R?t bytesencoded((s"/usr/local/lib/python2.6/codecs.pyRZscCsQ|djo|iiƒ}n|ii|ƒ}|i||iƒ\}}|S(N(R,RwRlRR1(R&R^R?R}((s"/usr/local/lib/python2.6/codecs.pyRls  cCs7|iiƒ}|i||iƒ\}}|idƒS(Ni(RwRZRR1R](R&RmR?R}((s"/usr/local/lib/python2.6/codecs.pyRnscCs.|iiƒ}|i||iƒ\}}|S(s4 Return the next decoded line from the input stream.(RwRsRR1(R&R?R}((s"/usr/local/lib/python2.6/codecs.pyRsscCs|S(N((R&((s"/usr/local/lib/python2.6/codecs.pyRtscCs+|i||iƒ\}}|ii|ƒS(N(R R1RxRG(R&R?t bytesdecoded((s"/usr/local/lib/python2.6/codecs.pyRGscCs:di|ƒ}|i||iƒ\}}|ii|ƒS(NR4(RIR R1RxRG(R&RJR?R~((s"/usr/local/lib/python2.6/codecs.pyRK$scCs|iiƒ|iiƒdS(N(RwR8Rx(R&((s"/usr/local/lib/python2.6/codecs.pyR8*s cCs||i|ƒS(s? Inherit all other methods from the underlying stream. (RF(R&RRL((s"/usr/local/lib/python2.6/codecs.pyRM/scCs|S(N((R&((s"/usr/local/lib/python2.6/codecs.pyRN6scCs|iiƒdS(N(RFRO(R&RPRQRR((s"/usr/local/lib/python2.6/codecs.pyRS9sN(R)R(R2t data_encodingt file_encodingR6RZR,RlRnRsRtRGRKR8RLRMRNRS(((s"/usr/local/lib/python2.6/codecs.pyR|Ês         trbR.icCs­Þ~initial threadšª¶Jµœ‡ ­Þ~initial threadšª¶JÀœ‡PÊ­Þ~initial threadšª¶JМ‡ƒ|dj od|jo|d}nti|||ƒ}|djo|St|ƒ}t||i|i|ƒ}||_|S(s­ Open an encoded file using the given mode and return a wrapped version providing transparent encoding/decoding. Note: The wrapped version will only accept the object format defined by the codecs, i.e. Unicode objects for most builtin codecs. Output is also codec dependent and will usually be Unicode as well. Files are always opened in binary mode, even if no binary mode was specified. This is done to avoid data loss due to encodings using 8-bit values. The default file mode is 'rb' meaning to open the file in binary read mode. encoding specifies the encoding which is to be used for the file. errors may be given to define the error handling. It defaults to 'strict' which causes ValueErrors to be raised in case an encoding error occurs. buffering has the same meaning as for the builtin open() API. It defaults to line buffered. The returned wrapped file object provides an extra attribute .encoding which allows querying the used encoding. This attribute is only available if an encoding was specified as parameter. tbN(R,t __builtin__RRRuR$R#R{(tfilenametmodeR{R1t bufferingtfiletinfotsrw((s"/usr/local/lib/python2.6/codecs.pyR>s     cCsl|djo |}nt|ƒ}t|ƒ}t||i|i|i|i|ƒ}||_||_|S(så Return a wrapped version of file which provides transparent encoding translation. Strings written to the wrapped file are interpreted according to the given data_encoding and then written to the original file as string using file_encoding. The intermediate encoding will usually be Unicode but depends on the specified codecs. Strings are read from the file using file_encoding and then passed back to the caller as string using data_encoding. If file_encoding is not given, it defaults to data_encoding. errors may be given to define the error handling. It defaults to 'strict' which causes ValueErrors to be raised in case an encoding error occurs. The returned wrapped file object provides two extra attributes .data_encoding and .file_encoding which reflect the given parameters of the same name. The attributes can be used for introspection by Python programs. N( R,RR|RR R$R#RR€(R‡RR€R1t data_infot file_infotsr((s"/usr/local/lib/python2.6/codecs.pyRjs      cCs t|ƒiS(sž Lookup up the codec for the given encoding and return its encoder function. Raises a LookupError in case the encoding cannot be found. (RR(R{((s"/usr/local/lib/python2.6/codecs.pyt getencoderscCs t|ƒiS(sž Lookup up the codec for the given encoding and return its decoder function. Raises a LookupError in case the encoding cannot be found. (RR (R{((s"/usr/local/lib/python2.6/codecs.pyt getdecoderšscCs0t|ƒi}|djot|ƒ‚n|S(s÷ Lookup up the codec for the given encoding and return its IncrementalEncoder class or factory function. Raises a LookupError in case the encoding cannot be found or the codecs doesn't provide an incremental encoder. N(RR!R,t LookupError(R{tencoder((s"/usr/local/lib/python2.6/codecs.pytgetincrementalencoder¤s  cCs0t|ƒi}|djot|ƒ‚n|S(s÷ Lookup up the codec for the given enc­Þ~initial threadšª¶JÜœ‡ ­Þ~initial threadšª¶J眇PÊ|­Þ~initial threadšª¶Jöœ‡oding and return its IncrementalDecoder class or factory function. Raises a LookupError in case the encoding cannot be found or the codecs doesn't provide an incremental decoder. N(RR"R,R(R{tdecoder((s"/usr/local/lib/python2.6/codecs.pytgetincrementaldecoder²s  cCs t|ƒiS(s´ Lookup up the codec for the given encoding and return its StreamReader class or factory function. Raises a LookupError in case the encoding cannot be found. (RR$(R{((s"/usr/local/lib/python2.6/codecs.pyt getreaderÀscCs t|ƒiS(s´ Lookup up the codec for the given encoding and return its StreamWriter class or factory function. Raises a LookupError in case the encoding cannot be found. (RR#(R{((s"/usr/local/lib/python2.6/codecs.pyt getwriterÊsckskt|ƒ||}x-|D]%}|i|ƒ}|o |VqqW|idtƒ}|o |VndS(s¾ Encoding iterator. Encodes the input strings from the iterator using a IncrementalEncoder. errors and kwargs are passed through to the IncrementalEncoder constructor. R4N(R‘RRX(titeratorR{R1tkwargsRR0toutput((s"/usr/local/lib/python2.6/codecs.pyt iterencodeÔs  ckskt|ƒ||}x-|D]%}|i|ƒ}|o |VqqW|idtƒ}|o |VndS(s¾ Decoding iterator. Decodes the input strings from the iterator using a IncrementalDecoder. errors and kwargs are passed through to the IncrementalDecoder constructor. R4N(R“R RX(R–R{R1R—R’R0R˜((s"/usr/local/lib/python2.6/codecs.pyt iterdecodeæs  cCs%h}x|D]}||| dict Return a dictionary where elements of the rng sequence are mapped to themselves. ((trngtresti((s"/usr/local/lib/python2.6/codecs.pytmake_identity_dictús cCsLh}x?|iƒD]1\}}||jo|||s„         @(!1*DõQt,&           ­Þ~initial threadšª¶J‡t ­Þ~initial threadšª¶J‡PÊ­Þ~initial threadšª¶J#‡­Þ~initial threadšª¶J-‡­Þ~initial threadšª¶Jž‡­Þ~initial threadšª¶Jž‡­Þ~initial threadšª¶J Ÿ‡­Þ~initial threadšª¶JŸ‡­Þ~initial threadšª¶J+Ÿ‡¼0ÅÿÿÿPÄÿÿÿ,­Þ~initial threadšª¶J7Ÿ‡/usr/local/lib/python2.6/encodings/encodings­Þ~initial threadšª¶JOŸ‡¼ ­Þ~initial threadšª¶JPŸ‡0Åÿÿÿ¶/­Þ~initial threadšª¶JPŸ‡/usr/local/lib/python2.6/encodings/encodings.so­Þ~initial threadšª¶J’Ÿ‡ ­Þ~initial threadšª¶JŸ‡0Åÿÿÿ¶5­Þ~initial threadšª¶J¨Ÿ‡/usr/local/lib/python2.6/encodings/encodingsmodule.so­Þ~initial threadšª¶JÀŸ‡ ­Þ~initial threadšª¶JËŸ‡0Åÿÿÿ¶/­Þ~initial threadšª¶JÖŸ‡/usr/local/lib/python2.6/encodings/encodings.py­Þ~initial threadšª¶J퟇ ­Þ~initial threadšª¶JøŸ‡0Åÿÿÿ¶0­Þ~initial threadšª¶J ‡/usr/local/lib/python2.6/encodings/encodings.pyc­Þ~initial threadšª¶J ‡­Þ~initial threadšª¶J+ ‡¼ Åÿÿÿ@Äÿÿÿ*­Þ~initial threadšª¶J6 ‡/usr/local/lib/python2.6/encodings/aliases­Þ~initial threadšª¶JM ‡¼ ­Þ~initial threadšª¶JX ‡ Åÿÿÿ¶-­Þ~initial threadšª¶Jc ‡/usr/local/lib/python2.6/encodings/aliases.so­Þ~initial threadšª¶Jz ‡ ­Þ~initial threadšª¶J… ‡ Åÿÿÿ¶3­Þ~initial threadšª¶J ‡/usr/local/lib/python2.6/encodings/aliasesmodule.so­Þ~initial threadšª¶J§ ‡ ­Þ~initial threadšª¶J² ‡ Åÿÿÿ¶-­Þ~initial threadšª¶J½ ‡/usr/local/lib/python2.6/encodings/aliases.py­Þ~initial threadšª¶JÖ ‡­Þ~initial threadšª¶Já ‡½0Äÿÿÿ}­Þ~initial threadšª¶Jì ‡stat["($ˆ+ñ²JÚ²JÚ²J9 Ú²J­Þ~initial threadšª¶Jö ‡½ ­Þ~initial threadšª¶J¡‡ Àÿÿÿ¶.­Þ~initial threadšª¶J ¡‡/usr/local/lib/python2.6/encodings/aliases.pyc­Þ~initial threadšª¶J$¡‡­Þ~initial threadšª¶J.¡‡½¾ÿÿÿ}­Þ~initial threadšª¶J9¡‡stat[§*$ú4ª¶Jß²Jß²J"Þ²J­Þ~initial threadšª¶JC¡‡½ ­Þ~initial threadšª¶JO¡‡°Ë­Þ~initial threadšª¶J_¡‡Ñò Ú²Jc@s`dZh0dd6dd6dd6dd6dd6dd6dd6dd 6dd 6dd 6dd 6dd 6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd 6dd!6d"d#6d"d$6d"d%6d&d'6d&d(6d)d*6d)d+6d,d-6d,d.6d/d06d/d16d2d36d2d46d5d66d5d76d8d96d8d:6d;d<6d;d=6d>d?6d>d@6dAdB6dAdC6dDdE6dDdF6dDdG6dDdH6dIdJ6dIdK6dIdL6dMdN6dMdO6dMdP6dMdQ6dMdR6dSdT6dSdU6dSdV6dWdX6dWdY6dWdZ6d[d\6d[d]6d[d^6d_d`6d_da6d_db6dcdd6dcde6dcdf6dgdh6dgdi6dgdj6dkdl6dkdm6dkdn6dkdo6dpdq6dpdr6dpds6dtdu6dtdv6dtdw6dxdy6dxdz6dxd{6d|d}6d|d~6d|d6d€d6d€d‚6d€dƒ6d„d…6d„d†6d„d‡6d„dˆ6d‰dŠ6d‰d‹6d‰dŒ6d‰d6dŽd6dŽd6dŽd‘6d’d“6d’d”6d•d–6d•d—6d•d˜6d™dš6d›dœ6d›d6d›dž6dŸd 6dŸd¡6dŸd¢6dŸd£6dŸd¤6dŸd¥6dŸd¦6d§d¨6d©dª6d©d«6d©d¬6d©d­6d©d®6d©d¯6d©d°6d©d±6d²d³6d²d´6d²dµ6d¶d·6d¸d¹6d¸dº6d¸d»6d¼d½6d¼d¾6d¼d¿6dÀdÁ6dÀdÂ6dÀdÃ6dÄdÅ6dÄdÆ6dÇdÈ6dÇdÉ6dÊdË6dÊdÌ6dÍdÎ6dÍdÏ6dÐdÑ6dÐdÒ6dÓdÔ6dÓdÕ6dÓdÖ6d×dØ6d×dÙ6d×dÚ6d×dÛ6d×dÜ6d×dÝ6dÞdß6dÞdà6dÞdá6dâdã6dâdä6dâdå6dædç6dædè6dædé6dædê6dædë6dædì6dídî6dídï6dídð6dñdò6dñdó6dñdô6dñdõ6dñdö6d÷dø6d÷dù6d÷dú6d÷dû6d÷dü6d÷dý6dþdÿ6dþd6dþd6dþd6dþd6dþd6dd6dd6dd6dd 6dd 6dd 6d d 6d d6d d6d d6d d6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd6dd 6dd!6dd"6d#d$6d#d%6d#d&6d#d'6d#d(6d)d*6d)d+6d)d,6d)d-6d)d.6d)d/6d0d16d0d26d3d46d5d66d5d76d5d86d5d96d5d:6d5d;6d5d<6d5d=6d5d>6d5d?6d5d@6d5dA6dBdC6dDdE6dFdG6dHdI6dHdJ6dKdL6dMdN6dOdP6dQdR6dQdS6dQdT6dQdU6dVdW6dVdX6dVdY6dZd[6d\d]6d\d^6d\d_6d\d`6dadb6dadc6dadd6dedf6dedg6dedh6didj6dkdl6dkdm6dkdn6dkdo6dkdp6dqdr6dqds6dtdu6dtdv6dwdx6dwdy6dzd{6dzd|6d}d~6dd€6dd‚6ddƒ6dd„6d…d†6d…d‡6d…dˆ6d…d‰6d…dŠ6d‹dŒ6ddŽ6dd6ZdS(‘s< Encoding Aliases Support This module is used by the encodings package search function to map encodings names to module names. Note that the search function normalizes the encoding names before doing the lookup, so the mapping will have to map normalized encoding names to module names. Contents: The following aliases dictionary contains mappings of all IANA character set names for which the Python core library provides codecs. In addition to these, a few Python specific codec aliases have also been added. tasciit646sansi_x3.4_1968tansi_x3_4_1968sansi_x3.4_1986tcp367tcsasciitibm367t iso646_ussiso_646.irv_1991tiso_ir_6tustus_asciit base64_codectbase64tbase_64tbig5tbig5_twtcsbig5t big5hkscst big5_hkscsthkscst bz2_codectbz2tcp037t037tcsibm037t ebcdic_cp_cat ebcdic_cp_nlt ebcdic_cp_ust ebcdic_cp_wttibm037tibm039tcp1026t1026t csibm1026tibm1026tcp1140t1140tibm1140tcp1250t1250t windows_1250tcp1251t1251t windows_1251tcp1252t1252t windows_1252tcp1253t1253t windows_1253tcp1254t1254t windows_1254tcp1255t1255t windows_1255tcp1256t1256t windows_1256tcp1257t1257t windows_1257tcp1258t1258t windows_1258tcp424t424tcsibm424t ebcdic_cp_hetibm424tcp437t437tcspc8codepage437tibm437tcp500t500tcsibm500t ebcdic_cp_bet ebcdic_cp_chtibm500tcp775t775t cspc775baltictibm775tcp850t850tcspc850multilingualtibm850tcp852t852tcspcp852tibm852tcp855t855tcsibm855tibm855tcp857t857tcsibm857tibm857tcp860t860tcsibm860tibm860tcp861t861tcp_istcsibm861t­Þ~initial threadšª¶J–¡‡­Þ~initial threadšª¶J¢¡‡½°ÿÿÿ}­Þ~initial threadšª¶J­¡‡stat[§*$ú4šª¶Jß²Jß²J"Þ²J­Þ~initial threadšª¶J·¡‡½ ­Þ~initial threadšª¶JÁ¡‡°Ë­Þ~initial threadšª¶JÛ¡‡ibm861tcp862t862tcspc862latinhebrewtibm862tcp863t863tcsibm863tibm863tcp864t864tcsibm864tibm864tcp865t865tcsibm865tibm865tcp866t866tcsibm866tibm866tcp869t869tcp_grtcsibm869tibm869tcp932t932tms932tmskanjitms_kanjitcp949t949tms949tuhctcp950t950tms950t euc_jis_2004tjisx0213t eucjis2004t euc_jis2004t euc_jisx0213t eucjisx0213teuc_jpteucjptujistu_jisteuc_krteuckrtkoreantksc5601t ks_c_5601tks_c_5601_1987tksx1001t ks_x_1001tgb18030t gb18030_2000tgb2312tchinesetcsiso58gb231280teuc_cnteuccnt eucgb2312_cnt gb2312_1980t gb2312_80t iso_ir_58tgbkt936tcp936tms936t hex_codecthext hp_roman8troman8tr8t csHPRoman8thzthzgbthz_gbt hz_gb_2312t iso2022_jpt csiso2022jpt iso2022jpt iso_2022_jpt iso2022_jp_1t iso2022jp_1t iso_2022_jp_1t iso2022_jp_2t iso2022jp_2t iso_2022_jp_2tiso2022_jp_2004tiso_2022_jp_2004tiso2022jp_2004t iso2022_jp_3t iso2022jp_3t iso_2022_jp_3tiso2022_jp_extt iso2022jp_exttiso_2022_jp_extt iso2022_krt csiso2022krt iso2022krt iso_2022_krt iso8859_10t csisolatin6t iso_8859_10tiso_8859_10_1992t iso_ir_157tl6tlatin6t iso8859_11tthait iso_8859_11tiso_8859_11_2001t iso8859_13t iso_8859_13tl7tlatin7t iso8859_14t iso_8859_14tiso_8859_14_1998t iso_celtict iso_ir_199tl8tlatin8t iso8859_15t iso_8859_15tl9tlatin9t iso8859_16t iso_8859_16tiso_8859_16_2001t iso_ir_226tl10tlatin10t iso8859_2t csisolatin2t iso_8859_2tiso_8859_2_1987t iso_ir_101tl2tlatin2t iso8859_3t csisolatin3t iso_8859_3tiso_8859_3_1988t iso_ir_109tl3tlatin3t iso8859_4t csisolatin4t iso_8859_4tiso_8859_4_1988t iso_ir_110tl4tlatin4t iso8859_5tcsisolatincyrillictcyrillict iso_8859_5tiso_8859_5_1988t iso_ir_144t iso8859_6tarabictasmo_708tcsisolatinarabictecma_114t iso_8859_6tiso_8859_6_1987t iso_ir_127t iso8859_7tcsisolatingreektecma_118telot_928tgreektgreek8t iso_8859_7tiso_8859_7_1987t iso_ir_126t iso8859_8tcsisolatinhebrewthebrewt iso_8859_8tiso_8859_8_1988t iso_ir_138t iso8859_9t csisolatin5t iso_8859_9tiso_8859_9_1989t iso_ir_148tl5tlatin5tjohabtcp1361tms1361tkoi8_rtcskoi8rtlatin_1t8859tcp819t csisolatin1tibm819tiso8859t iso8859_1t iso_8859_1tiso_8859_1_1987t iso_ir_100tl1tlatintlatin1t mac_cyrillict maccyrillict mac_greektmacgreekt mac_icelandt macicelandt mac_latin2tmaccentraleuropet maclatin2t mac_romantmacromant mac_turkisht macturkishtmbcstdbcstptcp154t csptcp154tpt154tcp154scyrillic-asiant quopri_codectquopritquoted_printabletquotedprintabletrot_13trot13t shift_jist csshiftjistshiftjistsjists_jistshift_jis_2004t shiftjis2004t sjis_2004t s_jis_2004tshift_jisx0213t shiftjisx0213t sjisx0213t s_jisx0213ttactisttis260ttis_620ttis620t tis_620_0ttis_620_2529_0ttis_620_2529_1t iso_ir_166tutf_16tu16tutf16t utf_16_betunicodebigunmarkedtutf_16bet utf_16_letunicodelittleunmarkedtutf_16letutf_32tu32tutf32t utf_32_betutf_32bet utf_32_letutf_32letutf_7tu7tutf7tunicode_1_1_utf_7tutf_8tu8tutftutf8t utf8_ucs2t utf8_ucs4tuu_codectuut zlib_codectziptzlibN(t__doc__taliases(((s-/usr/local/lib/python2.6/encodings/aliases.pytsb­Þ~initial threadšª¶J桇 ­Þ~initial threadšª¶Jñ¡‡°Ë ­Þ~initial threadšª¶Jÿ¡‡ ­Þ~initial threadšª¶J¢‡ ­Þ~initial threadšª¶J¢‡°Ë­Þ~initial threadšª¶J¢‡­Þ~initial threadšª¶J'¢‡8­Þ~initial threadšª¶J3¢‡Ýÿÿÿÿ­Þ~initial threadšª¶JA¢‡Ýà­Þ~initial threadšª¶J£‡­Þ~initial threadšª¶J,£‡­Þ~initial threadšª¶JP£‡­Þ~initial threadšª¶J^£‡­Þ~initial threadšª¶Jo£‡¼0ÅÿÿÿPÄÿÿÿ.­Þ~initial threadšª¶JŠ£‡/usr/local/lib/python2.6/encodings/__builtin__­Þ~initial threadšª¶J££‡¼ ­Þ~initial threadšª¶J¯£‡0Åÿÿÿ¶1­Þ~initial threadšª¶J»£‡/usr/local/lib/python2.6/encodings/__builtin__.so­Þ~initial threadšª¶JÓ£‡ ­Þ~initial threadšª¶JÞ£‡0Åÿÿÿ¶7­Þ~initial threadšª¶J꣇/usr/local/lib/python2.6/encodings/__builtin__module.so­Þ~initial threadšª¶J¤‡ ­Þ~initial threadšª¶J ¤‡0Åÿÿÿ¶1­Þ~initial threadšª¶J¤‡/usr/local/lib/python2.6/encodings/__builtin__.py­Þ~initial threadšª¶J5¤‡ ­Þ~initial threadšª¶J@¤‡0Åÿÿÿ¶2­Þ~initial threadšª¶JL¤‡/usr/local/lib/python2.6/encodings/__builtin__.pyc­Þ~initial threadšª¶Jd¤‡­Þ~initial threadšª¶J˜¤‡­Þ~initial threadšª¶J¦¤‡­Þ~initial threadšª¶Jͤ‡¼°×ÿÿÿÐÖÿÿÿ(­Þ~initial threadšª¶JÙ¤‡/usr/local/lib/python2.6/encodings/ascii­Þ~initial threadšª¶Jñ¤‡¼ ­Þ~initial threadšª¶Jü¤‡°×ÿÿÿ¶+­Þ~initial threadšª¶J¥‡/usr/local/lib/python2.6/encodings/ascii.so­Þ~initial threadšª¶J ¥‡ ­Þ~initial threadšª¶J+¥‡°×ÿÿÿ¶1­Þ~initial threadšª¶J7¥‡/usr/local/lib/python2.6/encodings/asciimodule.so­Þ~initial threadšª¶JN¥‡ ­Þ~initial threadšª¶JY¥‡°×ÿÿÿ¶+­Þ~initial threadšª¶Je¥‡/usr/local/lib/python2.6/encodings/ascii.py­Þ~initial threadšª¶J¥‡­Þ~initial threadšª¶JŠ¥‡½ÀÖÿÿÿ}­Þ~initial threadšª¶J•¥‡stat[#($/Üñ²JÚ²JÚ²JàÚ²J­Þ~initial threadšª¶JŸ¥‡½ ­Þ~initial threadšª¶Jª¥‡°Òÿÿÿ¶,­Þ~initial threadšª¶J¶¥‡/usr/local/lib/python2.6/encodings/ascii.pyc­Þ~initial threadšª¶JÏ¥‡­Þ~initial threadšª¶JÚ¥‡½ Ñÿÿÿ}­Þ~initial threadšª¶J楇stat[¨*$5ª¶Jß²Jß²J Þ²J­Þ~initial threadšª¶J𥇽 ­Þ~initial threadšª¶Jû¥‡àË ­Þ~initial threadšª¶J ¦‡Ñò Ú²Jc@s»dZddkZdeifd„ƒYZdeifd„ƒYZdeifd„ƒYZd eeifd „ƒYZd eeifd „ƒYZd eefd„ƒYZd„ZdS(s Python 'ascii' Codec Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. iÿÿÿÿNtCodeccBseZeiZeiZRS((t__name__t __module__tcodecst ascii_encodetencodet ascii_decodetdecode(((s+/usr/local/lib/python2.6/encodings/ascii.pyR s tIncrementalEncodercBseZed„ZRS(cCsti||iƒdS(Ni(RRterrors(tselftinputtfinal((s+/usr/local/lib/python2.6/encodings/ascii.pyRs(RRtFalseR(((s+/usr/local/lib/python2.6/encodings/ascii.pyRstIncrementalDecodercBseZed„ZRS(cCsti||iƒdS(Ni(RRR (R R R ((s+/usr/local/lib/python2.6/encodings/ascii.pyRs(RRR R(((s+/usr/local/lib/python2.6/encodings/ascii.pyRst StreamWritercBseZRS((RR(((s+/usr/local/lib/python2.6/encodings/ascii.pyRst StreamReadercBseZRS((RR(((s+/usr/local/lib/python2.6/encodings/ascii.pyRstStreamConvertercBseZeiZeiZRS((RRRRRRR(((s+/usr/local/lib/python2.6/encodings/ascii.pyR"s cCs:tidddtidtidtdtdtdtƒS( NtnametasciiRRtincrementalencodertincrementaldecodert streamwritert streamreader( Rt CodecInfoRRRRRRR(((s+/usr/local/lib/python2.6/encodings/ascii.pyt getregentry)s   ( t__doc__RRRRRRRR(((s+/usr/local/lib/python2.6/encodings/ascii.pyts ­Þ~initial threadšª¶J¦‡ ­Þ~initial threadšª¶J!¦‡½@’ÿÿÿ}­Þ~initial threadšª¶J-¦‡stat[¨*$5šª¶Jß²Jß²J Þ²J­Þ~initial threadšª¶J7¦‡½ ­Þ~initial threadšª¶Jm¦‡àË­Þ~initial threadšª¶J{¦‡­Þ~initial threadšª¶J‘¦‡­Þ~initial threadšª¶J·¦‡­Þ~initial threadšª¶JȦ‡­Þ~initial threadšª¶J‹§‡­Þ~initial threadšª¶J𧇠­Þ~initial threadšª¶Jا‡6t,@päÿÿÿ­Þ~initial threadšª¶J秇6 ­Þ~initial threadšª¶Jô§‡6t,@päÿÿÿ­Þ~initial threadšª¶J¨‡6 ­Þ~initial threadšª¶J ¨‡6t,@päÿÿÿ­Þ~initial threadšª¶J¨‡6 ­Þ~initial threadšª¶J%¨‡:êêÿÿÿ Þÿÿÿ ­Þ~initial threadšª¶J0¨‡boundstest.py­Þ~initial threadšª¶J@¨‡:º­Þ~initial threadšª¶J\¨‡F0âÿÿÿ0­Þ~initial threadšª¶Jm¨‡/usr/home/gnn/Personal/Code/Networking/PCS/tests­Þ~initial threadšª¶Jw¨‡F­Þ~initial threadšª¶J…¨‡¾0âÿÿÿ0Éÿÿÿ>­Þ~initial threadšª¶J¨‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/boundstest.py}­Þ~initial threadšª¶J°¨‡stat[u™´éé:(ª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶J»¨‡¾­Þ~initial threadšª¶Jɨ‡¼ðßÿÿÿäÿÿÿ ­Þ~initial threadšª¶JÔ¨‡boundstest.py}­Þ~initial threadšª¶J㨇stat[u™´éé:(ª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶Jí¨‡¼ ­Þ~initial threadšª¶Jù¨‡ðßÿÿÿ¶ ­Þ~initial threadšª¶J©‡boundstest.py­Þ~initial threadšª¶J©‡­Þ~initial threadšª¶J©‡½€Õÿÿÿ}­Þ~initial threadšª¶JA©‡stat[u™´éé:(ª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶JL©‡½­Þ~initial threadšª¶JX©‡½PÖÿÿÿ}­Þ~initial threadšª¶Jd©‡stat[u™´éé:(ª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶Jn©‡½ ­Þ~initial threadšª¶J|©‡Þ­Þ~initial threadšª¶J‡©‡Þ ­Þ~initial threadšª¶J‘©‡Þ­Þ~initial threadšª¶J›©‡Þ ­Þ~initial threadšª¶J¦©‡à˵­Þ~initial threadšª¶Jµ©‡ dns = dnsrr() self.assertRaises(pcs.FieldBoundsError, setattr, dns, 'name', "The walrus and the carpenter were walking close at hand. The wept like anything to see such quantities of sand. The Walrus and the Carpenter Were walking close at hand; They wept like anything to see Such quantities of sand: If this were only cleared away, They said, it would be grand! If seven maids with seven mops Swept it for half a year. Do you suppose, the Walrus said, That they could get it clear? I doubt it, said the Carpenter, And shed a bitter tear.The time has come the walrus said to speak of many things of shoes and ships and sealing wax and cabbages and Kings, and why the sea is boiling hot and whether pigs have whings. Caloo Callay or frabjous day for cabbages and kings?") def test_allbits(self): packet = boundaryPacket() for field in packet._layout: self.assertRaises(pcs.FieldBoundsError, setattr, packet, field.name, 2 ** field.width) self.assertRaises(pcs.FieldBoundsError, setattr, packet, field.name, -1) if __name__ == '__main__': unittest.main() ­Þ~initial threadšª¶JÀ©‡­­Þ~initial threadšª¶JΩ‡­Þ~initial threadšª¶Jੇ­Þ~initial threadšª¶J漢¼$\Ü0äÿÿÿ ­Þ~initial threadšª¶Jú©‡boundstest.py}­Þ~initial threadšª¶J ª‡stat[u™´éé:(šª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶Jª‡¼ ­Þ~initial threadšª¶Jª‡êêÿÿÿ¶ ­Þ~initial threadšª¶J+ª‡boundstest.py­Þ~initial threadšª¶J9ª‡­Þ~initial threadšª¶JDª‡½æÿÿÿ}­Þ~initial threadšª¶JOª‡stat[u™´éé:(šª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶JYª‡½ ­Þ~initial threadšª¶Jcª‡6t,@àåÿÿÿ­Þ~initial threadšª¶Joª‡6 ­Þ~initial threadšª¶J{ª‡Þ­Þ~initial threadšª¶J†ª‡Þ­Þ~initial threadšª¶Jª‡½ äÿÿÿ}­Þ~initial threadšª¶Jœª‡stat[u™´éé:(šª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶J¦ª‡½ ­Þ~initial threadšª¶J±ª‡àË­Þ~initial threadšª¶JÁª‡# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id:$ # # Author: George V. Neville-Neil # # Description: A simple test of all the bound checking code in PCS import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs from pcs.packets.ipv4 import * from pcs.packets.ethernet import * from pcs.packets.dns import * class boundaryPacket(pcs.Packet): """Define a packet full of bit fields for use in testing. """ _layout = pcs.Layout() def __init__(self, bytes = None): f1 = pcs.Field("f1", 1) f2 = pcs.Field("f2", 2) f3 = pcs.Field("f3", 3) f4 = pcs.Field("f4", 4) f5 = pcs.Field("f5", 5) f6 = pcs.Field("f6", 6) f7 = pcs.Field("f7", 7) f8 = pcs.Field("f8", 8) f9 = pcs.Field("f9", 9) f10 = pcs.Field("f10", 10) f11 = pcs.Field("f11", 11) f12 = pcs.Field("f12", 12) f13 = pcs.Field("f13", 13) f14 = pcs.Field("f14", 14) f15 = pcs.Field("f15", 15) f16 = pcs.Field("f16", 16) f17 = pcs.Field("f17", 17) f18 = pcs.Field("f18", 18) f19 = pcs.Field("f19", 19) f20 = pcs.Field("f20", 20) f21 = pcs.Field("f21", 21) f22 = pcs.Field("f22", 22) f23 = pcs.Field("f23", 23) f24 = pcs.Field("f24", 24) f25 = pcs.Field("f25", 25) f26 = pcs.Field("f26", 26) f27 = pcs.Field("f27", 27) f28 = pcs.Field("f28", 28) f29 = pcs.Field("f29", 29) f30 = pcs.Field("f30", 30) f31 = pcs.Field("f31", 31) f32 = pcs.Field("f32", 32) pcs.Packet.__init__(self, [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32], bytes = None) class boundsTestCase(unittest.TestCase): def test_field(self): ip = ipv4() assert (ip != None) self.assertRaises(pcs.FieldBoundsError, setattr, ip, 'version', 9999) def test_stringfield(self): ether = ethernet() self.assertRaises(pcs.FieldBoundsError, setattr, ether, 'src', "\x00\x00\x00\x00\x00\x00\x00") def test_lengthvaluefield(self): ­Þ~initial threadšª¶Jͪ‡ ­Þ~initial threadšª¶JÙª‡Þ­Þ~initial threadšª¶Jäª‡Þ ­Þ~initial threadšª¶Js²‡à˵­Þ~initial threadšª¶J†²‡ dns = dnsrr() self.assertRaises(pcs.FieldBoundsError, setattr, dns, 'name', "The walrus and the carpenter were walking close at hand. The wept like anything to see such quantities of sand. The Walrus and the Carpenter Were walking close at hand; They wept like anything to see Such quantities of sand: If this were only cleared away, They said, it would be grand! If seven maids with seven mops Swept it for half a year. Do you suppose, the Walrus said, That they could get it clear? I doubt it, said the Carpenter, And shed a bitter tear.The time has come the walrus said to speak of many things of shoes and ships and sealing wax and cabbages and Kings, and why the sea is boiling hot and whether pigs have whings. Caloo Callay or frabjous day for cabbages and kings?") def test_allbits(self): packet = boundaryPacket() for field in packet._layout: self.assertRaises(pcs.FieldBoundsError, setattr, packet, field.name, 2 ** field.width) self.assertRaises(pcs.FieldBoundsError, setattr, packet, field.name, -1) if __name__ == '__main__': unittest.main() ­Þ~initial threadšª¶J‘²‡­ ­Þ~initial threadšª¶J³‡àË­Þ~initial threadšª¶J$³‡­Þ~initial threadšª¶J.³‡­Þ~initial threadšª¶J!´‡­Þ~initial threadšª¶J2´‡­Þ~initial threadšª¶J¨µ‡¼ÀÇÿÿÿÐËÿÿÿ0­Þ~initial threadšª¶Jµµ‡/usr/home/gnn/Personal/Code/Networking/PCS/tests}­Þ~initial threadšª¶JÔµ‡stat[s™ýAééÏ'ª¶Jšª¶Jšª¶J”•¶J­Þ~initial threadšª¶JÞµ‡¼­Þ~initial threadšª¶J쵇¼\|ÛÌÿÿÿ0­Þ~initial threadšª¶J÷µ‡/usr/home/gnn/Personal/Code/Networking/PCS/tests}­Þ~initial threadšª¶J¶‡stat[s™ýAééÏ'ª¶Jšª¶Jšª¶J”•¶J­Þ~initial threadšª¶J¶‡¼­Þ~initial threadšª¶J)¶‡¼à×ÿÿÿ×ÿÿÿ9­Þ~initial threadšª¶J4¶‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/unittest­Þ~initial threadšª¶JP¶‡¼ ­Þ~initial threadšª¶J[¶‡à×ÿÿÿ¶<­Þ~initial threadšª¶Jh¶‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/unittest.so­Þ~initial threadšª¶J„¶‡ ­Þ~initial threadšª¶J¶‡à×ÿÿÿ¶B­Þ~initial threadšª¶J›¶‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/unittestmodule.so­Þ~initial threadšª¶J·¶‡ ­Þ~initial threadšª¶J¶‡à×ÿÿÿ¶<­Þ~initial threadšª¶Jζ‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/unittest.py­Þ~initial threadšª¶J鶇 ­Þ~initial threadšª¶Jô¶‡à×ÿÿÿ¶=­Þ~initial threadšª¶J·‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/unittest.pyc­Þ~initial threadšª¶J.·‡­Þ~initial threadšª¶J=·‡¼à×ÿÿÿ×ÿÿÿ!­Þ~initial threadšª¶JH·‡/usr/local/lib/python2.6/unittest­Þ~initial threadšª¶Jc·‡¼ ­Þ~initial threadšª¶Jn·‡à×ÿÿÿ¶$­Þ~initial threadšª¶Jz·‡/usr/local/lib/python2.6/unittest.so­Þ~initial threadšª¶J‘·‡ ­Þ~initial threadšª¶Jœ·‡à×ÿÿÿ¶*­Þ~initial threadšª¶J¨·‡/usr/local/lib/python2.6/unittestmodule.so­Þ~initial threadšª¶J¾·‡ ­Þ~initial threadšª¶JÉ·‡à×ÿÿÿ¶$­Þ~initial threadšª¶JÔ·‡/usr/local/lib/python2.6/unittest.py­Þ~initial threadšª¶Jð·‡­Þ~initial threadšª¶Jü·‡½ðÖÿÿÿ}­Þ~initial threadšª¶J¸‡stat[±%$("ø²JײJײJƒy@ײJ­Þ~initial threadšª¶Je¸‡½ ­Þ~initial threadšª¶Jq¸‡àÒÿÿÿ¶%­Þ~initial threadšª¶J~¸‡/usr/local/lib/python2.6/unittest.pyc­Þ~initial threadšª¶J™¸‡­Þ~initial threadšª¶J¤¸‡½PÑÿÿÿ}­Þ~initial threadšª¶J°¸‡stat[ï.¤8Qª¶Jã²Jã²J¤‰Hã²J­Þ~initial threadšª¶Jº¸‡½ ­Þ~initial threadšª¶JƸ‡àË­Þ~initial threadšª¶Jظ‡Ñò ײJc@sìdZdZdZddd!ZddkZddkZddkZddkZddkZdd d d d d ddgZ e i dddgƒei d d+jo d„Z nd„Z eZd„ZdZdd,d„ƒYZd d-d„ƒYZd d.d„ƒYZd efd„ƒYZd d/d„ƒYZeƒZdd„Zed„Zdeed „Zdeed!„Zd"d0d#„ƒYZd$efd%„ƒYZd d1d&„ƒYZ d'd2d(„ƒYZ!e!Z"e#d)joe"d*dƒndS(3sˆ Python unit testing framework, based on Erich Gamma's JUnit and Kent Beck's Smalltalk testing framework. This module contains the core framework classes that form the basis of specific test cases and suites (TestCase, TestSuite etc.), and also a text-based utility class for running the tests and reporting the results (TextTestRunner). Simple usage: import unittest class IntegerArithmenticTestCase(unittest.TestCase): def testAdd(self): ## test method names begin 'test*' self.assertEquals((1 + 2), 3) self.assertEquals(0 + 1, 1) def testMultiply(self): self.assertEquals((0 * 10), 0) self.assertEquals((5 * 8), 40) if __name__ == '__main__': unittest.main() Further information is available in the bundled documentation, and from http://docs.python.org/lib/module-unittest.html Copyright (c) 1999-2003 Steve Purcell This module is free software, and you may redistribute it and/or modify it under the same terms as Python itself, so long as this copyright message and disclaimer are retained in their original form. IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. s Steve Purcells stephen_purcell at yahoo dot coms#Revision: 1.63 $i iþÿÿÿiÿÿÿÿNt TestResulttTestCaset TestSuitetTextTestRunnert TestLoadertFunctionTestCasetmaintdefaultTestLoadertgetTestCaseNamest makeSuitet findTestCasesicCsddk}t|ƒttfjoHx@|D]8}|tjo ti}n|i||ƒodSq,WdS|i||ƒSdS(Niÿÿÿÿii(t __builtin__ttypettupletlistttypest ClassTypet isinstance(tobjtclsinfoR tcls((s$/usr/local/lib/python2.6/unittest.pyRGs   cs dtf‡fd†ƒY}|S(s,Convert a cmp= function into a key= functiontKcs eZd„Z‡fd†ZRS(cSs ||_dS(N(R(tselfR((s$/usr/local/lib/python2.6/unittest.pyt__init__Tscsˆ|i|iƒdjS(Niÿÿÿÿ(R(Rtother(tmycmp(s$/usr/local/lib/python2.6/unittest.pyt__lt__Vs(t__name__t __module__RR((R(s$/usr/local/lib/python2.6/unittest.pyRSs (tobject(RR((Rs$/usr/local/lib/python2.6/unittest.pyt _CmpToKeyQscCsd|i|ifS(Ns%s.%s(RR(R((s$/usr/local/lib/python2.6/unittest.pyt _strclassasicBszeZdZd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „ZRS( sÙHolder for test result information. Test results are automatically managed by the TestCase and TestSuite classes, and do not need to be explicitly manipulated by writers of tests­Þ~initial threadšª¶J㸇­Þ~initial threadšª¶J½p’ÿÿÿ}­Þ~initial threadšª¶Jú¸‡stat[ï.¤8Qšª¶Jã²Jã²J¤‰Hã²J­Þ~initial threadšª¶J¹‡½ ­Þ~initial threadšª¶JU¹‡àË­Þ~initial threadšª¶Jf¹‡. Each instance holds the total number of tests run, and collections of failures and errors that occurred among those test runs. The collections contain tuples of (testcase, exceptioninfo), where exceptioninfo is the formatted traceback of the error that occurred. cCs(g|_g|_d|_t|_dS(Ni(tfailuresterrorsttestsRuntFalset shouldStop(R((s$/usr/local/lib/python2.6/unittest.pyRqs   cCs|id|_dS(s-Called when the given test is about to be runiN(R"(Rttest((s$/usr/local/lib/python2.6/unittest.pyt startTestwscCsdS(s'Called when the given test has been runN((RR%((s$/usr/local/lib/python2.6/unittest.pytstopTest{scCs&|ii||i||ƒfƒdS(smCalled when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info(). N(R!tappendt_exc_info_to_string(RR%terr((s$/usr/local/lib/python2.6/unittest.pytaddErrorscCs&|ii||i||ƒfƒdS(sdCalled when an error has occurred. 'err' is a tuple of values as returned by sys.exc_info().N(R R(R)(RR%R*((s$/usr/local/lib/python2.6/unittest.pyt addFailure…scCsdS(s-Called when a test has completed successfullyN((RR%((s$/usr/local/lib/python2.6/unittest.pyt addSuccessŠscCs+t|iƒt|iƒjodjSS(s.Tells whether or not this result was a successi(tlenR R!(R((s$/usr/local/lib/python2.6/unittest.pyt wasSuccessfulŽscCs t|_dS(s*Indicates that the tests should be abortedN(tTrueR$(R((s$/usr/local/lib/python2.6/unittest.pytstop’scCs’|\}}}x%|o|i|ƒo |i}qW||ijo/|i|ƒ}diti||||ƒƒSditi|||ƒƒS(s>Converts a sys.exc_info()-style tuple of values into a string.t(t_is_relevant_tb_levelttb_nexttfailureExceptiont_count_relevant_tb_levelstjoint tracebacktformat_exception(RR*R%texctypetvaluettbtlength((s$/usr/local/lib/python2.6/unittest.pyR)–s cCsd|iijS(Nt __unittest(ttb_framet f_globals(RR<((s$/usr/local/lib/python2.6/unittest.pyR3¢scCs=d}x0|o(|i|ƒ o|d7}|i}q W|S(Nii(R3R4(RR<R=((s$/usr/local/lib/python2.6/unittest.pyR6¥s  cCs2dt|iƒ|it|iƒt|iƒfS(Ns!<%s run=%i errors=%i failures=%i>(Rt __class__R"R.R!R (R((s$/usr/local/lib/python2.6/unittest.pyt__repr__¬s(RRt__doc__RR&R'R+R,R-R/R1R)R3R6RB(((s$/usr/local/lib/python2.6/unittest.pyRfs           cBsKeZdZeZdd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z d „Zd „Zd „Zdd„Zd„Zd„Zd„Zdd„Zdd„Zdd„Zd„Zdd„Zdd„Zddd„Zddd„ZeZZeZ Z!eZ"Z#eZ$Z%eZ&eZ'Z(eZ)RS(s«A class whose instances are single test cases. By default, the test code itself should be placed in a method named 'runTest'. If the fixture may be used for many test cases, create as many test methods as are needed. When instantiating such a TestCase subclass, spec­Þ~initial threadšª¶Jr¹‡ ­Þ~initial threadšª¶J}¹‡àË­Þ~initial threadšª¶J¹‡ify in the constructor arguments the name of the test method that the instance is to execute. Test authors should subclass TestCase for their own tests. Construction and deconstruction of the test's environment ('fixture') can be implemented by overriding the 'setUp' and 'tearDown' methods respectively. If it is necessary to override the __init__ method, the base class __init__ method must always be called. It is important that subclasses should not change the signature of their __init__ method, since instances of the classes are instantiated automatically by parts of the framework in order to be run. trunTestcCsXy(||_t||ƒ}|i|_Wn)tj otd|i|f‚nXdS(sÅCreate an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name. sno such test method in %s: %sN(t_testMethodNametgetattrRCt_testMethodDoctAttributeErrort ValueErrorRA(Rt methodNamet testMethod((s$/usr/local/lib/python2.6/unittest.pyRÍs cCsdS(sAHook method for setting up the test fixture before exercising it.N((R((s$/usr/local/lib/python2.6/unittest.pytsetUpÚscCsdS(sAHook method for deconstructing the test fixture after testing it.N((R((s$/usr/local/lib/python2.6/unittest.pyttearDownÞscCsdS(Ni((R((s$/usr/local/lib/python2.6/unittest.pytcountTestCasesâscCstƒS(N(R(R((s$/usr/local/lib/python2.6/unittest.pytdefaultTestResultåscCs.|i}|o|idƒdiƒpdS(såReturns a one-line description of the test, or None if no description has been provided. The default implementation of this method returns the first line of the specified test method's docstring. s iN(RGtsplittstriptNone(Rtdoc((s$/usr/local/lib/python2.6/unittest.pytshortDescriptionès cCsdt|iƒ|ifS(Ns%s.%s(RRARE(R((s$/usr/local/lib/python2.6/unittest.pytidòscCs.t|ƒt|ƒj otS|i|ijS(N(R R#RE(RR((s$/usr/local/lib/python2.6/unittest.pyt__eq__õscCs ||j S(N((RR((s$/usr/local/lib/python2.6/unittest.pyt__ne__ûscCstt|ƒ|ifƒS(N(thashR RE(R((s$/usr/local/lib/python2.6/unittest.pyt__hash__þscCsd|it|iƒfS(Ns%s (%s)(RERRA(R((s$/usr/local/lib/python2.6/unittest.pyt__str__scCsdt|iƒ|ifS(Ns<%s testMethod=%s>(RRARE(R((s$/usr/local/lib/python2.6/unittest.pyRBscCsq|djo|iƒ}n|i|ƒt||iƒ}z y|iƒWn3tj o ‚n|i||iƒƒdSXt }y|ƒt }Wn]|i j o|i ||iƒƒn3tj o ‚n|i||iƒƒnXy|i ƒWn8tj o ‚n$|i||iƒƒt }nX|o|i|ƒnWd|i|ƒXdS(N(RRROR&RFRERLtKeyboardInterruptR+t _exc_infoR#R0R5R,RMR-R'(RtresultRKtok((s$/usr/local/lib/python2.6/unittest.pytruns@    cOs|i||ŽS(N(R_(Rtargstkwds(­Þ~initial threadšª¶J™¹‡ ­Þ~initial threadšª¶J¤¹‡àË­Þ~initial threadšª¶JÁ¹‡(s$/usr/local/lib/python2.6/unittest.pyt__call__+scCs+|iƒt||iƒƒ|iƒdS(s6Run the test without collecting errors in a TestResultN(RLRFRERM(R((s$/usr/local/lib/python2.6/unittest.pytdebug.s cCs tiƒS(s¡Return a version of sys.exc_info() with the traceback frame minimised; usually the top level of the traceback frame is not needed. (tsystexc_info(R((s$/usr/local/lib/python2.6/unittest.pyR\4scCs|i|‚dS(s)Fail immediately, with the given message.N(R5(Rtmsg((s$/usr/local/lib/python2.6/unittest.pytfail;scCs|o|i|‚ndS(s(Fail the test if the expression is true.N(R5(RtexprRf((s$/usr/local/lib/python2.6/unittest.pytfailIf?scCs|p|i|‚ndS(s,Fail the test unless the expression is true.N(R5(RRhRf((s$/usr/local/lib/python2.6/unittest.pyt failUnlessCscOsey|||ŽWn|j odSXt|dƒo |i}n t|ƒ}|id|‚dS(siFail unless an exception of class excClass is thrown by callableObj when invoked with arguments args and keyword arguments kwargs. If a different type of exception is thrown, it will not be caught, and the test case will be deemed to have suffered an error, exactly as for an unexpected exception. NRs %s not raised(thasattrRtstrR5(RtexcClasst callableObjR`tkwargstexcName((s$/usr/local/lib/python2.6/unittest.pytfailUnlessRaisesGs  cCs2||jp!|i|pd||f‚ndS(s[Fail if the two objects are unequal as determined by the '==' operator. s%r != %rN(R5(RtfirsttsecondRf((s$/usr/local/lib/python2.6/unittest.pytfailUnlessEqualXs cCs2||jo!|i|pd||f‚ndS(sYFail if the two objects are equal as determined by the '==' operator. s%r == %rN(R5(RRrRsRf((s$/usr/local/lib/python2.6/unittest.pyt failIfEqual`s icCsHtt||ƒ|ƒdjo$|i|pd|||f‚ndS(sKFail if the two objects are unequal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero. Note that decimal places (from zero) are usually not the same as significant digits (measured from the most signficant digit). is%r != %r within %r placesN(troundtabsR5(RRrRstplacesRf((s$/usr/local/lib/python2.6/unittest.pytfailUnlessAlmostEqualhs cCsHtt||ƒ|ƒdjo$|i|pd|||f‚ndS(sIFail if the two objects are equal as determined by their difference rounded to the given number of decimal places (default 7) and comparing to zero. Note that decimal places (from zero) are usually not the same as significant digits (measured from the most signficant digit). is%r == %r within %r placesN(RvRwR5(RRrRsRxRf((s$/usr/local/lib/python2.6/unittest.pytfailIfAlmostEqualts N(*RRRCtAssertionErrorR5RRLRMRNRORTRURVRWRYRZRBRRR_RbRcR\RgRiRjRqRtRuRyRzt assertEqualt assertEqualstassertNotEqualtassertNotEqualstassertAlmostEqualtassertAlmostEqualst­Þ~initial threadšª¶J³º‡ ­Þ~initial threadšª¶JÀº‡àË­Þ~initial threadšª¶JѺ‡assertNotAlmostEqualtassertNotAlmostEqualst assertRaisestassert_t assertTruet assertFalse(((s$/usr/local/lib/python2.6/unittest.pyR±sB           #               cBs€eZdZd d„Zd„ZeZd„Zd„Zd Z d„Z d„Z d„Z d„Z d „Zd „Zd „ZRS(s³A test suite is a composite test consisting of a number of TestCases. For use, create an instance of TestSuite, then add test case instances. When all tests have been added, the suite can be passed to a test runner, such as TextTestRunner. It will run the individual test cases in the order in which they were added, aggregating the results. When subclassing, do not forget to call the base class constructor. cCsg|_|i|ƒdS(N(t_teststaddTests(Rttests((s$/usr/local/lib/python2.6/unittest.pyR›s cCsdt|iƒ|ifS(Ns <%s tests=%s>(RRARˆ(R((s$/usr/local/lib/python2.6/unittest.pyRBŸscCs.t|ƒt|ƒj otS|i|ijS(N(R R#Rˆ(RR((s$/usr/local/lib/python2.6/unittest.pyRV¤scCs ||j S(N((RR((s$/usr/local/lib/python2.6/unittest.pyRW©scCs t|iƒS(N(titerRˆ(R((s$/usr/local/lib/python2.6/unittest.pyt__iter__¯scCs.d}x!|iD]}||iƒ7}qW|S(Ni(RˆRN(RtcasesR%((s$/usr/local/lib/python2.6/unittest.pyRN²s  cCsst|dƒptdƒ‚nt|ttifƒo&t|ttfƒotdƒ‚n|i i |ƒdS(NRbs the test to add must be callablesNTestCases and TestSuites must be instantiated before passing them to addTest()( Rkt TypeErrorRR RRt issubclassRRRˆR((RR%((s$/usr/local/lib/python2.6/unittest.pytaddTest¸s cCsBt|tƒotdƒ‚nx|D]}|i|ƒq'WdS(Ns0tests must be an iterable of tests, not a string(Rt basestringRŽR(RRŠR%((s$/usr/local/lib/python2.6/unittest.pyR‰Âs cCs1x*|iD]}|ioPn||ƒq W|S(N(RˆR$(RR]R%((s$/usr/local/lib/python2.6/unittest.pyR_Ès   cOs|i||ŽS(N(R_(RR`Ra((s$/usr/local/lib/python2.6/unittest.pyRbÏscCs"x|iD]}|iƒq WdS(s7Run the tests without collecting errors in a TestResultN(RˆRc(RR%((s$/usr/local/lib/python2.6/unittest.pyRcÒs (N(RRRCRRBRZRVRWRRRYRŒRNRR‰R_RbRc(((s$/usr/local/lib/python2.6/unittest.pyR’s         cBszeZdZd d d d„Zd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z d „ZRS( sIA test case that wraps a test function. This is useful for slipping pre-existing test functions into the unittest framework. Optionally, set-up and tidy-up functions can be supplied. As with TestCase, the tidy-up ('tearDown') function will always be called if the set-up ('setUp') function ran successfully. cCs5ti|ƒ||_||_||_||_dS(N(RRt_FunctionTestCase__setUpFunct_FunctionTestCase__tearDownFunct_FunctionTestCase__testFunct_FunctionTestCase__description(RttestFuncRLRMt description((s$/usr/local/lib/python2­Þ~initial threadšª¶Jݺ‡ ­Þ~initial threadšª¶J躇àË­Þ~initial threadšª¶Jøº‡.6/unittest.pyRàs     cCs"|idj o|iƒndS(N(R’RR(R((s$/usr/local/lib/python2.6/unittest.pyRLèscCs"|idj o|iƒndS(N(R“RR(R((s$/usr/local/lib/python2.6/unittest.pyRMìscCs|iƒdS(N(R”(R((s$/usr/local/lib/python2.6/unittest.pyRDðscCs |iiS(N(R”R(R((s$/usr/local/lib/python2.6/unittest.pyRUóscCsgt|ƒt|ƒj otS|i|ijo6|i|ijo#|i|ijo|i|ijS(N(R R#R’R“R”R•(RR((s$/usr/local/lib/python2.6/unittest.pyRVös cCs ||j S(N((RR((s$/usr/local/lib/python2.6/unittest.pyRWÿscCs+tt|ƒ|i|i|i|ifƒS(N(RXR R’R“R”R•(R((s$/usr/local/lib/python2.6/unittest.pyRYscCsdt|iƒ|iifS(Ns%s (%s)(RRAR”R(R((s$/usr/local/lib/python2.6/unittest.pyRZscCsdt|iƒ|ifS(Ns<%s testFunc=%s>(RRAR”(R((s$/usr/local/lib/python2.6/unittest.pyRB scCsI|idj o|iS|ii}|o|idƒdiƒpdS(Ns i(R•RRR”RCRPRQ(RRS((s$/usr/local/lib/python2.6/unittest.pyRT s N(RRRCRRRRLRMRDRURVRWRYRZRBRT(((s$/usr/local/lib/python2.6/unittest.pyR×s         cBsSeZdZdZeZeZd„Zd„Z dd„Z dd„Z d„Z RS(s|This class is responsible for loading tests according to various criteria and returning them wrapped in a TestSuite R%cCsjt|tƒotdƒ‚n|i|ƒ}| ot|dƒo dg}n|it||ƒƒS(s<Return a suite of all tests cases contained in testCaseClasssYTest cases should not be derived from TestSuite. Maybe you meant to derive from TestCase?RD(RRRŽRRkt suiteClasstmap(Rt testCaseClasst testCaseNames((s$/usr/local/lib/python2.6/unittest.pytloadTestsFromTestCases  cCs|g}xft|ƒD]X}t||ƒ}t|ttifƒo*t|tƒo|i|i |ƒƒqqW|i |ƒS(s?Return a suite of all tests cases contained in the given module( tdirRFRR RRRRR(RœR˜(RtmoduleRŠtnameR((s$/usr/local/lib/python2.6/unittest.pytloadTestsFromModule(s c Csò|idƒ}|djoi|}xQ|oIytdi|ƒƒ}PWq&tj o|d=|p‚qrq&Xq&W|d}n|}x$|D]}|t||ƒ}}q’Wt|ƒtijo|i |ƒSt |tti fƒot |t ƒo|i|ƒSt|ƒtijo@t |tti fƒo't |t ƒot||iƒgƒSt |tƒo|St|dƒoV|ƒ}t |tƒo|St |t ƒot|gƒStd||fƒ‚ntd|ƒ‚dS(sTReturn a suite of all tests cases given a string specifier. The name may resolve either to a module, a test case class, a test method within a test case class, or a callable object which returns a TestCase or TestSuite instance. The method optionally resolves the names relative to a given module. t.iÿÿÿÿiRbs"calling %s returned %s, not a tests$don't know how to make test from: %sN(RPRRt __import__R­Þ~initial threadšª¶J»‡ ­Þ~initial threadšª¶J»‡àË­Þ~initial threadšª¶J»‡7t ImportErrorRFR Rt ModuleTypeR RRRRRœtUnboundMethodTypeRRRkRŽ( RRŸRžtpartst parts_copyRtparttparentR%((s$/usr/local/lib/python2.6/unittest.pytloadTestsFromName2sJ   cCs:g}|D]}||i||ƒq ~}|i|ƒS(s‚Return a suite of all tests cases found using the given sequence of string specifiers. See 'loadTestsFromName()'. (RªR˜(RtnamesRžt_[1]RŸtsuites((s$/usr/local/lib/python2.6/unittest.pytloadTestsFromNamesas-cCsR||id„}t|t|ƒƒ}|io|idt|iƒƒn|S(sLReturn a sorted sequence of method names found within testCaseClass cSs&|i|ƒott||ƒdƒS(NRb(t startswithRkRF(tattrnameRštprefix((s$/usr/local/lib/python2.6/unittest.pyt isTestMethodkstkey(ttestMethodPrefixtfilterRtsortTestMethodsUsingtsortR(RRšR²t testFnNames((s$/usr/local/lib/python2.6/unittest.pyRhs  N(RRRCR´tcmpR¶RR˜RœR RRRªR®R(((s$/usr/local/lib/python2.6/unittest.pyRs / cCs3tƒ}||_||_|o ||_n|S(N(RR¶R´R˜(R±t sortUsingR˜tloader((s$/usr/local/lib/python2.6/unittest.pyt _makeLoader{s     cCst||ƒi|ƒS(N(R¼R(RšR±Rº((s$/usr/local/lib/python2.6/unittest.pyR‚sR%cCst|||ƒi|ƒS(N(R¼Rœ(RšR±RºR˜((s$/usr/local/lib/python2.6/unittest.pyR …scCst|||ƒi|ƒS(N(R¼R (RžR±RºR˜((s$/usr/local/lib/python2.6/unittest.pyR ˆst_WritelnDecoratorcBs,eZdZd„Zd„Zdd„ZRS(s@Used to decorate file-like objects with a handy 'writeln' methodcCs ||_dS(N(tstream(RR¾((s$/usr/local/lib/python2.6/unittest.pyR’scCst|i|ƒS(N(RFR¾(Rtattr((s$/usr/local/lib/python2.6/unittest.pyt __getattr__•scCs)|o|i|ƒn|idƒdS(Ns (twrite(Rtarg((s$/usr/local/lib/python2.6/unittest.pytwriteln˜sN(RRRCRRÀRRRÃ(((s$/usr/local/lib/python2.6/unittest.pyR½s  t_TextTestResultcBsjeZdZddZddZd„Zd„Zd„Zd„Zd„Z d „Z d „Z d „Z RS( shA test result class that can print formatted text results to a stream. Used by TextTestRunner. t=iFt-cCsAti|ƒ||_|dj|_|dj|_||_dS(Ni(RRR¾tshowAlltdotst descriptions(RR¾RÉt verbosity((s$/usr/local/lib/python2.6/unittest.pyR¥s   cCs0|io|iƒp t|ƒSt|ƒSdS(N(RÉRTRl(RR%((s$/usr/local/lib/python2.6/unittest.pytgetDescription¬s cCsXti||ƒ|io:|ii|i|ƒƒ|iidƒ|iiƒndS(Ns ... (RR&RÇR¾RÁRËtflush(RR%((s$/usr/local/lib/python2.6/unittest.pyR&²s  cCs]ti||ƒ|io|iidƒn,|io!|iidƒ|iiƒndS(NR^R¡­Þ~initial threadšª¶J)»‡ ­Þ~initial threadšª¶J4»‡àË­Þ~initial threadšª¶JC»‡(RR-RÇR¾RÃRÈRÁRÌ(RR%((s$/usr/local/lib/python2.6/unittest.pyR-¹s   cCs`ti|||ƒ|io|iidƒn,|io!|iidƒ|iiƒndS(NtERRORtE(RR+RÇR¾RÃRÈRÁRÌ(RR%R*((s$/usr/local/lib/python2.6/unittest.pyR+Ás   cCs`ti|||ƒ|io|iidƒn,|io!|iidƒ|iiƒndS(NtFAILtF(RR,RÇR¾RÃRÈRÁRÌ(RR%R*((s$/usr/local/lib/python2.6/unittest.pyR,És   cCsO|ip |io|iiƒn|id|iƒ|id|iƒdS(NRÍRÏ(RÈRÇR¾RÃtprintErrorListR!R (R((s$/usr/local/lib/python2.6/unittest.pyt printErrorsÑscCsxxq|D]i\}}|ii|iƒ|iid||i|ƒfƒ|ii|iƒ|iid|ƒqWdS(Ns%s: %ss%s(R¾RÃt separator1RËt separator2(RtflavourR!R%R*((s$/usr/local/lib/python2.6/unittest.pyRÑ×s  #( RRRCRÓRÔRRËR&R-R+R,RÒRÑ(((s$/usr/local/lib/python2.6/unittest.pyRÄs         cBs5eZdZeiddd„Zd„Zd„ZRS(sÉA test runner class that displays results in textual form. It prints out the names of tests as they are run, errors as they occur, and a summary of the results at the end of the test run. icCs%t|ƒ|_||_||_dS(N(R½R¾RÉRÊ(RR¾RÉRÊ((s$/usr/local/lib/python2.6/unittest.pyRås cCst|i|i|iƒS(N(RÄR¾RÉRÊ(R((s$/usr/local/lib/python2.6/unittest.pyt _makeResultêsc Cs[|iƒ}tiƒ}||ƒtiƒ}||}|iƒ|ii|iƒ|i}|iid||djodpd|fƒ|iiƒ|iƒpž|iidƒt t |i |i fƒ\}}|o|iid|ƒn|o3|o|iidƒn|iid|ƒn|iid ƒn|iid ƒ|S( s&Run the given test case or test suite.sRan %d test%s in %.3fsitsR2sFAILED (s failures=%ds, s errors=%dt)tOK( RÖttimeRÒR¾RÃRÔR"R/RÁR™R.R R!( RR%R]t startTimetstopTimet timeTakenR_tfailedterrored((s$/usr/local/lib/python2.6/unittest.pyR_ís.        %  !(RRRCRdtstderrRRÖR_(((s$/usr/local/lib/python2.6/unittest.pyRßs t TestProgramcBsSeZdZdZdddeed„Zdd„Zd„Z d„Z d„Z RS( sA command-line program that runs a set of tests; this is primarily for making test modules conveniently executable. s Usage: %(progName)s [options] [test] [...] Options: -h, --help Show this message -v, --verbose Verbose output -q, --quiet Minimal output Examples: %(progName)s - run default set of tests %(progName)s MyTestSuite - run suite 'MyTestSuite' %(progName)s MyTestCase.testSomething - run MyTestCase.testSomething %(progName)s MyTestCase - run all 'test*' test methods in MyTestCase t__main__cCsÚt|ƒtdƒjoFt|ƒ|_x=|idƒdD]}t|i|ƒ|_q<Wn ||_|djo ti}nd|_||_ ||_ ||_ t i i|dƒ|_|i|ƒ|iƒdS(NR2R¡ii­Þ~initial threadšª¶Jz»‡ ­Þ~initial threadšª¶J†»‡àˬ ­Þ~initial threadšª¶J•»‡(R R¢RžRPRFRRRdtargvRÊt defaultTestt testRunnert testLoadertostpathtbasenametprogNamet parseArgstrunTests(RRžRäRãRåRæR¨((s$/usr/local/lib/python2.6/unittest.pyR s        cCs0|o |GHn|i|iGHtidƒdS(Ni(tUSAGEt__dict__Rdtexit(RRf((s$/usr/local/lib/python2.6/unittest.pyt usageExit3s c CsCddk}y |i|dddddgƒ\}}xc|D][\}}|djo|iƒn|djo d |_n|djo d|_q>q>Wt|ƒd jo-|idjo|ii|iƒ|_ dSt|ƒd jo ||_ n|if|_ |i ƒWn%|i j o}|i|ƒnXdS(NiÿÿÿÿithHvqthelptverbosetquiets-hs-Hs--helps-qs--quietis-vs --verbosei(s-hs-Hs--help(s-qs--quiet(s-vs --verbose( tgetoptRðRÊR.RäRRRæR RžR%t testNamest createTeststerror(RRãRõtoptionsR`toptR;Rf((s$/usr/local/lib/python2.6/unittest.pyRë8s*      # cCs"|ii|i|iƒ|_dS(N(RæR®RöRžR%(R((s$/usr/local/lib/python2.6/unittest.pyR÷OscCsŽt|ittifƒo?y|id|iƒ}Wqdtj o|iƒ}qdXn |i}|i|iƒ}t i |i ƒ ƒdS(NRÊ( RRåR RRRÊRŽR_R%RdRïR/(RRåR]((s$/usr/local/lib/python2.6/unittest.pyRìSs N( RRRCRíRRRRRRðRëR÷Rì(((s$/usr/local/lib/python2.6/unittest.pyRá s    RâRž(ii(((((((($RCt __author__t __email__t __version__RÚRdR8RçRt__all__textendt version_infoRRR t __metaclass__RR>RRRRRRRRR¼R¹RR R R½RÄRRáRR(((s$/usr/local/lib/python2.6/unittest.pyt-sD         KáE@]    B.S ­Þ~initial threadšª¶J¡»‡¤ ­Þ~initial threadšª¶J¬»‡àË­Þ~initial threadšª¶J·»‡­Þ~initial threadšª¶J»‡­Þ~initial threadšª¶JŸ¼‡­Þ~initial threadšª¶JŸ¼‡­Þ~initial threadšª¶Jݼ‡¼Åÿÿÿ Äÿÿÿ5­Þ~initial threadšª¶J鼇/usr/home/gnn/Personal/Code/Networking/PCS/tests/time­Þ~initial threadšª¶J½‡¼ ­Þ~initial threadšª¶J½‡Åÿÿÿ¶8­Þ~initial threadšª¶J½‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/time.so­Þ~initial threadšª¶J8½‡ ­Þ~initial threadšª¶JC½‡Åÿÿÿ¶>­Þ~initial threadšª¶JO½‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/timemodule.so­Þ~initial threadšª¶Jj½‡ ­Þ~initial threadšª¶Ju½‡Åÿÿÿ¶8­Þ~initial threadšª¶J½‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/time.py­Þ~initial threadšª¶Jœ½‡ ­Þ~initial threadšª¶J§½‡Åÿÿÿ¶9­Þ~initial threadšª¶J²½‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/time.pyc­Þ~initial threadšª¶Jͽ‡­Þ~initial threadšª¶JÚ½‡¼Åÿÿÿ Äÿÿÿ­Þ~initial threadšª¶J彇/usr/local/lib/python2.6/time­Þ~initial threadšª¶Jú½‡¼ ­Þ~initial threadšª¶J¾‡Åÿÿÿ¶ ­Þ~initial threadšª¶J¾‡/usr/local/lib/python2.6/time.so­Þ~initial threadšª¶J%¾‡ ­Þ~initial threadšª¶J0¾‡Åÿÿÿ¶&­Þ~initial threadšª¶J;¾‡/usr/local/lib/python2.6/timemodule.so­Þ~initial threadšª¶J[¾‡ ­Þ~initial threadšª¶Jf¾‡Åÿÿÿ¶ ­Þ~initial threadšª¶Jr¾‡/usr/local/lib/python2.6/time.py­Þ~initial threadšª¶Jˆ¾‡ ­Þ~initial threadšª¶J“¾‡Åÿÿÿ¶!­Þ~initial threadšª¶Jž¾‡/usr/local/lib/python2.6/time.pyc­Þ~initial threadšª¶J´¾‡­Þ~initial threadšª¶J¾¾‡¼Åÿÿÿ Äÿÿÿ+­Þ~initial threadšª¶Jɾ‡/usr/local/lib/python2.6/plat-freebsd8/time­Þ~initial threadšª¶Jß¾‡¼ ­Þ~initial threadšª¶J꾇Åÿÿÿ¶.­Þ~initial threadšª¶Jö¾‡/usr/local/lib/python2.6/plat-freebsd8/time.so­Þ~initial threadšª¶J ¿‡ ­Þ~initial threadšª¶J¿‡Åÿÿÿ¶4­Þ~initial threadšª¶J"¿‡/usr/local/lib/python2.6/plat-freebsd8/timemodule.so­Þ~initial threadšª¶J:¿‡ ­Þ~initial threadšª¶JE¿‡Åÿÿÿ¶.­Þ~initial threadšª¶JP¿‡/usr/local/lib/python2.6/plat-freebsd8/time.py­Þ~initial threadšª¶Jg¿‡ ­Þ~initial threadšª¶Jr¿‡Åÿÿÿ¶/­Þ~initial threadšª¶J}¿‡/usr/local/lib/python2.6/plat-freebsd8/time.pyc­Þ~initial threadšª¶J”¿‡­Þ~initial threadšª¶JŸ¿‡¼Åÿÿÿ Äÿÿÿ$­Þ~initial threadšª¶J©¿‡/usr/local/lib/python2.6/lib-tk/time­Þ~initial threadšª¶JÀ¿‡¼ ­Þ~initial threadšª¶JË¿‡Åÿÿÿ¶'­Þ~initial threadšª¶JÖ¿‡/usr/local/lib/python2.6/lib-tk/time.so­Þ~initial threadšª¶Jí¿‡ ­Þ~initial threadšª¶Jø¿‡Åÿÿÿ¶-­Þ~initial threadšª¶JÀ‡/usr/local/lib/python2.6/lib-tk/timemodule.so­Þ~initial threadšª¶JÀ‡ ­Þ~initial threadšª¶J%À‡Åÿÿÿ¶'­Þ~initial threadšª¶J0À‡/usr/local/lib/python2.6/lib-tk/time.py­Þ~initial threadšª¶JLÀ‡ ­Þ~initial threadšª¶JWÀ‡Åÿÿÿ¶(­Þ~initial threadšª¶JbÀ‡/usr/local/lib/python2.6/lib-tk/time.pyc­Þ~initial threadšª¶JyÀ‡­Þ~initial threadšª¶J„À‡¼Åÿÿÿ Äÿÿÿ%­Þ~initial threadšª¶JÀ‡/usr/local/lib/python2.6/lib-old/time­Þ~initial threadšª¶J¥À‡¼ ­Þ~initial threadšª¶J°À‡Åÿÿÿ¶(­Þ~initial threadšª¶J»À‡/usr/local/lib/python2.6/lib-old/time.so­Þ~initial threadšª¶J½À‡ ­Þ~initial threadšª¶J¾À‡Åÿÿÿ¶.­Þ~initial threadšª¶J¾À‡/usr/local/lib/python2.6/lib-old/timemodule.so­Þ~initial threadšª¶J¿À‡ ­Þ~initial threadšª¶J¿À‡Åÿÿÿ¶(­Þ~initial threadšª¶J¿À‡/usr/local/lib/python2.6/lib-old/time.py­Þ~initial threadšª¶J¿À‡ ­Þ~initial threadšª¶J¿À‡Åÿÿÿ¶)­Þ~initial threadšª¶J¿À‡/usr/local/lib/python2.6/lib-old/time.pyc­Þ~initial threadšª¶J¿À‡­Þ~initial threadšª¶J¿À‡¼Åÿÿÿ Äÿÿÿ)­Þ~initial threadšª¶J¿À‡/usr/local/lib/python2.6/lib-dynload/time­Þ~initial threadšª¶J¿À‡¼ ­Þ~initial threadšª¶J¿À‡Åÿÿÿ¶,­Þ~initial threadšª¶J¶Á‡/usr/local/lib/python2.6/lib-dynload/time.so­Þ~initial threadšª¶JÑÁ‡­Þ~initial threadšª¶JàÁ‡½ðÃÿÿÿ}­Þ~initial threadšª¶JíÁ‡stat[]ÎíØíª¶J¬²Jë²J=f4¬²J­Þ~initial threadšª¶J÷Á‡½ ­Þ~initial threadšª¶J‡Tà s0Áÿÿÿ­Þ~initial threadšª¶J‡T ­Þ~initial threadšª¶J‡€Bc-,­Þ~initial threadšª¶J)‡/usr/local/lib/python2.6/lib-dynload/time.so­Þ~initial threadšª¶JB‡­Þ~initial threadšª¶JM‡½°Àÿÿÿ}­Þ~initial threadšª¶JY‡stat[]ÎíØíª¶J¬²Jë²J=f4¬²J­Þ~initial threadšª¶Jc‡½ ­Þ~initial threadšª¶Jm‡à¡s­Þ~initial threadšª¶J~‡ELF >@`K@8@¤-¤-000èˆFˆFˆF  Påtdœ-œ-œ-CSQGA2H* P#'(I+OLJ$-D&M>N:;<9/R%=KE0!67,)?4C5".@B18F3 €H ¨P°Ø $  ˆ* ˜* œ-0DˆF(H8HHHPH JÞ8/Ì2É ÷…ñÿˆFOƒ†² 0)Õ,"12^‘`§º‡Vþ€ J ÑÍö=+qLËŸ+ì•–ìÿ1l=©EñÿJæk|& ˆ*ty»¯Ø·>ñÿJ ñÿPHQñÿèKvÃFtÇMå; O_DYNAMIC_GLOBAL_OFFSET_TABLE__init_fini__cxa_finalize_Jv_RegisterClassesPyImport_ImportModuleNoBlockPyObject_CallMethod_PyTime_DoubleToTimetPyExc_ValueErrorPyErr_SetStringPyArg_ParsePyDict_GetItemStringPyInt_AsLongPyArg_ParseTuplelocaltimestrlenstrftimefreemallocPyErr_NoMemoryPyString_FromStringAndSizemktimePyFloat_FromDoublePyExc_OverflowErrorPyArg_UnpackTuple_Py_NoneStructPyString_FromStringPyFloat_AsDoublePyErr_OccurredasctimegettimeofdayPyExc_IOErrorPyErr_SetFromErrno__errorPyStructSequence_NewPyInt_FromLonggmtimefloorfmodPyEval_SaveThreadselectPyEval_RestoreThreadclockstrncpyPyModule_AddIntConstantPy_BuildValuePyModule_AddObjectinittimePy_InitModule4_64Py_IgnoreEnvironmentFlagPyModule_GetDictgetenvPyStructSequence_InitTypetzsetlibm.so.5libthr.so.3libc.so.7_edata__bss_start_endFBSD_1.0( °(zV4 °(zV°(zV000@HÀAò+ÈA­Þ~initial threadšª¶J¶Â‡8­Þ~initial threadšª¶J‡ÝPÿÿÿÿ­Þ~initial threadšª¶JЇÝð8­Þ~initial threadšª¶JÛ‡Ýð0­Þ~initial threadšª¶Jö‡Ýð8­Þ~initial threadšª¶JÇÝ0 0­Þ~initial threadšª¶JÇÝ0­Þ~initial threadšª¶JcÇ­Þ~initial threadšª¶JpÇ8­Þ~initial threadšª¶JÇÝ0ÿÿÿÿ­Þ~initial threadšª¶JÇÝc­Þ~initial threadšª¶J¿Ã‡Ic0­Þ~initial threadšª¶JCćI ­Þ~initial threadšª¶JoćTð s­Þ~initial threadšª¶J{ćT ­Þ~initial threadšª¶J‰Ä‡Tà sÁÿÿÿ­Þ~initial threadšª¶J”ćT ­Þ~initial threadšª¶JžÄ‡Tð s­Þ~initial threadšª¶J¨Ä‡T­Þ~initial threadšª¶JÁćtÄÿÿÿ­Þ~initial threadšª¶JÐćt­Þ~initial threadšª¶Jìć!<อÞ~initial threadšª¶Jýć/etc/localtime­Þ~initial threadšª¶JŇ! ­Þ~initial threadšª¶JŇ<อÞ~initial threadšª¶J(Ň/etc/localtime­Þ~initial threadšª¶J9Ň­Þ~initial threadšª¶JCŇ½ÀÕþÿÿ}­Þ~initial threadšª¶JOŇstatY¢$Zkª¶J¹6²J¹6²J¿ ¹6²J­Þ~initial threadšª¶JZŇ½ ­Þ~initial threadšª¶JdŇ@Öþÿÿè¡Ç ­Þ~initial threadšª¶J‚ŇTZif2랦pŸºë` †p¡šÍ`¢eâp£ƒéà¤j®p¥5§`¦SÊð§‰`¨3¬ð¨þ¥àªŽðªÞ‡à«ópð¬¾ià­ÓRð®žK௳4ð°~-౜Qp²gJ`³|3p´G,`µ\p¶'`·;÷p¸ð`¹Ùp¹æÒ`»õð»Æ´`¼ä×ð½¯Ðà¾Ä¹ð¿²àÀ¤›ðÁo”à„}ðÃOvàÄd_ðÅ/XàÆM|pÇ:àÈ-^pÈøW`Ê @pÊØ9`ˈðpÒ#ôpÒ`ûàÓuäðÔ@ÝàÕUÆðÖ ¿à×5¨ðØ¡àÙŠðÙàƒàÚþ§pÛÀeàÜÞ‰pÝ©‚`Þ¾kp߉d`àžMpáiF`â~/pãI(`ä^påW.àæG-ðç7àè'ðéòàêñðêöÔàëæÓðìÖ¶àíÆµðî¿Ó`ï¯ÒpðŸµ`ñ´pò—`óo–pô_y`õOxpö?[`÷/Zpø(wàùÐp?›bà@o²pA„`BO”pCda`D/vpEDC`Eó¨ðG-_àGÓŠðI AàI³lðJí#àKœ‰pLÖ@`M|kpN¶"`O\MpP–`QÐp?›bà@o²pA„`BO”pCda`D/vpEDC`Eó¨ðG-_àGÓŠðI AàI³lðJí#àKœ‰pLÖ@`M|kpN¶"`O\MpP–`QÐp?›bà@o²pA„`BO”pCda`D/vpEDC`Eó¨ðG-_àGÓŠðI AàI³lðJí#àKœ‰pLÖ@`M|kpN¶"`O\MpP–`QÐp?›bà@o²pA„`BO”pCda`D/vpEDC`Eó¨ðG-_àGÓŠðI AàI³lðJí#àKœ‰pLÖ@`M|kpN¶"`O\MpP–`Q­Þ~initial threadšª¶J6ȇ/usr/home/gnn/Personal/Code/Networking/PCS/tests/traceback.pyc­Þ~initial threadšª¶JRȇ­Þ~initial threadšª¶J_ȇ¼Åÿÿÿ Äÿÿÿ"­Þ~initial threadšª¶Jjȇ/usr/local/lib/python2.6/traceback­Þ~initial threadšª¶J€È‡¼ ­Þ~initial threadšª¶J‹È‡Åÿÿÿ¶%­Þ~initial threadšª¶J—ȇ/usr/local/lib/python2.6/traceback.so­Þ~initial threadšª¶J­È‡ ­Þ~initial threadšª¶J¸È‡Åÿÿÿ¶+­Þ~initial threadšª¶JÄȇ/usr/local/lib/python2.6/tracebackmodule.so­Þ~initial threadšª¶JÚȇ ­Þ~initial threadšª¶JåȇÅÿÿÿ¶%­Þ~initial threadšª¶Jñȇ/usr/local/lib/python2.6/traceback.py­Þ~initial threadšª¶J ɇ­Þ~initial threadšª¶Jɇ½Äÿÿÿ}­Þ~initial threadšª¶J ɇstat[®%$Bõø²JײJײJ'+ײJ­Þ~initial threadšª¶J*ɇ½ ­Þ~initial threadšª¶J4ɇÀÿÿÿ¶&­Þ~initial threadšª¶J@ɇ/usr/local/lib/python2.6/traceback.pyc­Þ~initial threadšª¶JXɇ­Þ~initial threadšª¶Jcɇ½p¾ÿÿÿ}­Þ~initial threadšª¶Joɇstat[ª*$0Qª¶Jã²Jã²JK-Þ²J­Þ~initial threadšª¶Jyɇ½ ­Þ~initial threadšª¶J„ɇàË­Þ~initial threadšª¶JÈɇÑò ײJc@sBdZddkZddkZddkZddddddd d d d d dddgZddd„Zdd„Zd„Zddd„Z dd„Z dd„Z ddd„Z dd„Z d„Zd„Zd„Zddd„Zdd„Zddd „Zdddd!„Zddd"„Zddd#„Zd$„ZdS(%s@Extract, format and print information about Python stack traces.iÿÿÿÿNt extract_stackt extract_tbtformat_exceptiontformat_exception_onlyt format_listt format_stackt format_tbt print_exct format_exctprint_exceptiont print_lastt print_stacktprint_tbt tb_linenots cCs|i||ƒdS(N(twrite(tfiletstrt terminator((s%/usr/local/lib/python2.6/traceback.pyt_print scCsw|djo ti}nxV|D]N\}}}}t|d|||fƒ|ot|d|iƒƒq!q!WdS(syPrint the list of tuples as returned by extract_tb() or extract_stack() as a formatted stack trace to the given file.s File "%s", line %d, in %ss %sN(tNonetsyststderrRtstrip(textracted_listRtfilenametlinenotnametline((s%/usr/local/lib/python2.6/traceback.pyt print_lists  cCsfg}xY|D]Q\}}}}d|||f}|o|d|iƒ}n|i|ƒq W|S(s²Format a list of traceback entry tuples for printing. Given a list of tuples as returned by extract_tb() or extract_stack(), return a list of strings ready for printing. Each string in the resulting list corresponds to the item with the same index in the argument list. Each string ends in a newline; the strings may contain internal newlines as well, for those items whose source text line is not None. s File "%s", line %d, in %s s %s (Rtappend(RtlistRRRRtitem((s%/usr/local/lib/python2.6/traceback.pyRs c Cs"|djo ti}n|djo!ttdƒo ti}qHnd}xÍ|dj o¿|djp ||jo¥|i}|i}|i}|i}|i }t |d|||fƒt i |ƒt i |||iƒ} | ot |d| iƒƒn|i}|d}qQWdS(sPrint up to 'limit' stack trace entries from the traceback 'tb'. If 'limit' is omitted or None, all entries are printed. If 'file' is omitted or None, the output goes to sys.stderr; otherwise 'file' should be an open file or file-like object with a write() method. ttracebacklimitis File "%s", line %d, in %ss iN(RRRthasattrR!ttb_frameR tf_codet co_filenametco_nameRt linecachet checkcachetgetlinet f_globalsRttb_next( ttbtlimitRtntfRtcoRRR((s%/usr/local/lib/python2.6/traceback.pyR .s*   '       cCstt||ƒƒS(s6A shorthand for 'format_list(extract_stack(f, limit)).(RR(R,R-((s%/usr/local/lib/python2.6/traceback.pyRJsc Cs|djo!ttdƒo ti}q.ng}d}xÇ|dj o¹|djp ||joŸ|i}|i}|i}|i}|i}t i |ƒt i |||i ƒ} | o| i ƒ} nd} |i|||| fƒ|i}|d}q=W|S(síReturn list of up to limit pre-processed entries from traceback. This is useful for alternate formatting of stack traces. If 'limit' is omitted or None, all entries are extracted. A pre-processed stack trace entry is a quadruple (filename, line number, function name, text) representing the information that is usually printed for a stack trace. The text is a string with leading and trailing whitespa­Þ~initial threadšª¶JÔɇ­Þ~initial threadšª¶Jßɇ½ÿÿÿ}­Þ~initial threadšª¶Jêɇstat[ª*$0Qšª¶Jã²Jã²JK-Þ²J­Þ~initial threadšª¶Jõɇ½ ­Þ~initial threadšª¶JʇàË­Þ~initial threadšª¶Jʇce stripped; if the source is not available it is None. R!iiN(RR"RR!R#R R$R%R&R'R(R)R*RRR+( R,R-RR.R/RR0RRR((s%/usr/local/lib/python2.6/traceback.pyRNs* '       cCsŽ|djo ti}n|o!t|dƒt|||ƒnt||ƒ}x"|d D]}t||dƒq\Wt||ddƒdS(sùPrint exception up to 'limit' stack trace entries from 'tb' to 'file'. This differs from print_tb() in the following ways: (1) if traceback is not None, it prints a header "Traceback (most recent call last):"; (2) it prints the exception type and value after the stack trace; (3) if type is SyntaxError and value has the appropriate format, it prints the line where the syntax error occurred with a caret on the next line indicating the approximate position of the error. s"Traceback (most recent call last):iÿÿÿÿt RN(RRRRR R(tetypetvalueR,R-RtlinesR((s%/usr/local/lib/python2.6/traceback.pyR ns    cCsD|o dg}|t||ƒ}ng}|t||ƒ}|S(szFormat a stack trace and the exception information. The arguments have the same meaning as the corresponding arguments to print_exception(). The return value is a list of strings, each ending in a newline and some containing internal newlines. When these lines are concatenated and printed, exactly the same text is printed as does print_exception(). s#Traceback (most recent call last): (RR(R2R3R,R-R((s%/usr/local/lib/python2.6/traceback.pyRƒs  c Cspt|tƒp3t|tiƒp |djpt|ƒtjot||ƒgS|i}t |t ƒpt||ƒgSg}y|i \}\}}}}Wnt j onŸX|pd}|i d||fƒ|dj ol|i d|iƒƒ|dj o>|| iƒ} d„| Dƒ} |i ddi| ƒƒn|}n|i t||ƒƒ|S(sFormat the exception part of a traceback. The arguments are the exception type and value such as given by sys.last_type and sys.last_value. The return value is a list of strings, each ending in a newline. Normally, the list contains a single string; however, for SyntaxError exceptions, it contains several lines that (when printed) display detailed information about where the syntax error occurred. The message indicating which exception occurred is always the last string in the list. ss File "%s", line %d s %s css-x&|]}|iƒo|pdVqWdS(R1N(tisspace(t.0tc((s%/usr/local/lib/python2.6/traceback.pys Ãs s %s^ RN(t isinstancet BaseExceptionttypest InstanceTypeRttypeRt_format_final_exc_linet__name__t issubclasst SyntaxErrortargst ExceptionRRtlstriptjoin( R2R3tstypeR4tmsgRRtoffsettbadlinet caretspace((s%/usr/local/lib/python2.6/traceback.pyR”s.      cCsCt|ƒ}|djp| od|}nd||f}|S(sGReturn a list of a single line -- normal case for format_exception_onlys%s s%s: %s N(t _some_strR(R2R3tvaluestrR((s%/usr/local/lib/python2.6/traceback.pyR=Ës  cCs*yt|ƒSWndt|ƒiSXdS(Ns(RR<R>(R3((s%/usr/local/lib/python2.6/traceback.pyRJÔsc Cs_|djo ti}nz/tiƒ\}}}t|||||ƒ­Þ~initial threadšª¶Jʇ ­Þ~initial threadšª¶J&ʇàËS ­Þ~initial threadšª¶J5ʇWdd}}}XdS(s¾Shorthand for 'print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback, limit, file)'. (In fact, it uses sys.exc_info() to retrieve the same information in a thread-safe way.)N(RRRtexc_infoR (R-RR2R3R,((s%/usr/local/lib/python2.6/traceback.pyRÛs   c CsKz5tiƒ\}}}dit||||ƒƒSWdd}}}XdS(s%Like print_exc() but return a string.RN(RRLRDRR(R-R2R3R,((s%/usr/local/lib/python2.6/traceback.pyRès cCs=|djo ti}nttititi||ƒdS(snThis is a shorthand for 'print_exception(sys.last_type, sys.last_value, sys.last_traceback, limit, file)'.N(RRRR t last_typet last_valuetlast_traceback(R-R((s%/usr/local/lib/python2.6/traceback.pyR ñs  cCsa|djo:y t‚WqGtj otiƒdii}qGXntt||ƒ|ƒdS(s÷Print a stack trace from its invocation point. The optional 'f' argument can be used to specify an alternate stack frame at which to start. The optional 'limit' and 'file' arguments have the same meaning as for print_exception(). iN(RtZeroDivisionErrorRRLR#tf_backRR(R/R-R((s%/usr/local/lib/python2.6/traceback.pyR ús   cCsZ|djo:y t‚WqGtj otiƒdii}qGXntt||ƒƒS(s5Shorthand for 'format_list(extract_stack(f, limit))'.iN(RRPRRLR#RQRR(R/R-((s%/usr/local/lib/python2.6/traceback.pyRs   c CsP|djo:y t‚WqGtj otiƒdii}qGXn|djo!ttdƒo ti}qung}d}x¾|dj o°|djp ||jo–|i}|i }|i }|i }t i |ƒt i|||iƒ}|o|iƒ}nd}|i||||fƒ|i}|d}q„W|iƒ|S(ssExtract the raw traceback from the current stack frame. The return value has the same format as for extract_tb(). The optional 'f' and 'limit' arguments have the same meaning as for print_stack(). Each item in the list is a quadruple (filename, line number, function name, text), and the entries are in order from oldest to newest stack frame. iR!iiN(RRPRRLR#RQR"R!tf_linenoR$R%R&R'R(R)R*RRtreverse( R/R-RR.RR0RRR((s%/usr/local/lib/python2.6/traceback.pyRs4   '       cCs|iS(sRCalculate correct line number of traceback given in tb. Obsolete in 2.3. (R (R,((s%/usr/local/lib/python2.6/traceback.pyR 3s(t__doc__R'RR:t__all__RRRRR RRR RRR=RJRRR R RRR (((s%/usr/local/lib/python2.6/traceback.pyts2           7    "­Þ~initial threadšª¶JAʇK ­Þ~initial threadšª¶JLʇàË­Þ~initial threadšª¶JXʇ­Þ~initial threadšª¶Jbʇ­Þ~initial threadšª¶J´Ê‡­Þ~initial threadšª¶JÆÊ‡­Þ~initial threadšª¶Jãʇ­Þ~initial threadšª¶Jñʇ­Þ~initial threadšª¶J!̇­Þ~initial threadšª¶J0̇­Þ~initial threadšª¶JĊ¼à×ÿÿÿ×ÿÿÿ4­Þ~initial threadšª¶JȮ/usr/home/gnn/Personal/Code/Networking/PCS/tests/pcs­Þ~initial threadšª¶Jk̇¼ ­Þ~initial threadšª¶Jẇà×ÿÿÿ¶7­Þ~initial threadšª¶JƒÌ‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/pcs.so­Þ~initial threadšª¶JŸÌ‡ ­Þ~initial threadšª¶J«Ì‡à×ÿÿÿ¶=­Þ~initial threadšª¶J¶Ì‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/pcsmodule.so­Þ~initial threadšª¶JÝ̇ ­Þ~initial threadšª¶Jé̇à×ÿÿÿ¶7­Þ~initial threadšª¶Jõ̇/usr/home/gnn/Personal/Code/Networking/PCS/tests/pcs.py­Þ~initial threadšª¶J͇ ­Þ~initial threadšª¶J͇à×ÿÿÿ¶8­Þ~initial threadšª¶J(͇/usr/home/gnn/Personal/Code/Networking/PCS/tests/pcs.pyc­Þ~initial threadšª¶JD͇­Þ~initial threadšª¶JQ͇¼à×ÿÿÿ×ÿÿÿ­Þ~initial threadšª¶J]͇/usr/local/lib/python2.6/pcs­Þ~initial threadšª¶Jr͇¼ ­Þ~initial threadšª¶J}͇à×ÿÿÿ¶­Þ~initial threadšª¶J‰Í‡/usr/local/lib/python2.6/pcs.so­Þ~initial threadšª¶JŸÍ‡ ­Þ~initial threadšª¶JªÍ‡à×ÿÿÿ¶%­Þ~initial threadšª¶J¶Í‡/usr/local/lib/python2.6/pcsmodule.so­Þ~initial threadšª¶JÌ͇ ­Þ~initial threadšª¶J×͇à×ÿÿÿ¶­Þ~initial threadšª¶Jã͇/usr/local/lib/python2.6/pcs.py­Þ~initial threadšª¶Jù͇ ­Þ~initial threadšª¶J·à×ÿÿÿ¶ ­Þ~initial threadšª¶J·/usr/local/lib/python2.6/pcs.pyc­Þ~initial threadšª¶J&·­Þ~initial threadšª¶J1·¼à×ÿÿÿ×ÿÿÿ*­Þ~initial threadšª¶J<·/usr/local/lib/python2.6/plat-freebsd8/pcs­Þ~initial threadšª¶JT·¼ ­Þ~initial threadšª¶J^·à×ÿÿÿ¶-­Þ~initial threadšª¶Jj·/usr/local/lib/python2.6/plat-freebsd8/pcs.so­Þ~initial threadšª¶J‚· ­Þ~initial threadšª¶J·à×ÿÿÿ¶3­Þ~initial threadšª¶JÄ·/usr/local/lib/python2.6/plat-freebsd8/pcsmodule.so­Þ~initial threadšª¶JÝ· ­Þ~initial threadšª¶Jè·à×ÿÿÿ¶-­Þ~initial threadšª¶Jô·/usr/local/lib/python2.6/plat-freebsd8/pcs.py­Þ~initial threadšª¶J χ ­Þ~initial threadšª¶Jχà×ÿÿÿ¶.­Þ~initial threadšª¶J#χ/usr/local/lib/python2.6/plat-freebsd8/pcs.pyc­Þ~initial threadšª¶J:χ­Þ~initial threadšª¶JEχ¼à×ÿÿÿ×ÿÿÿ#­Þ~initial threadšª¶JPχ/usr/local/lib/python2.6/lib-tk/pcs­Þ~initial threadšª¶Jgχ¼ ­Þ~initial threadšª¶Jrχà×ÿÿÿ¶&­Þ~initial threadšª¶J~χ/usr/local/lib/python2.6/lib-tk/pcs.so­Þ~initial threadšª¶J•χ ­Þ~initial threadšª¶J¡Ï‡à×ÿÿÿ¶,­Þ~initial threadšª¶J¬Ï‡/usr/local/lib/python2.6/lib-tk/pcsmodule.so­Þ~initial threadšª¶JÄχ ­Þ~initial threadšª¶JÏχà×ÿÿÿ¶&­Þ~initial threadšª¶JÛχ/usr/local/lib/python2.6/lib-tk/pcs.py­Þ~initial threadšª¶Jóχ ­Þ~initial threadšª¶Jþχà×ÿÿÿ¶'­Þ~initial threadšª¶J Ї/usr/local/lib/python2.6/lib-tk/pcs.pyc­Þ~initial threadšª¶J!Ї­Þ~initial threadšª¶J%Ї¼à×ÿÿÿ×ÿÿÿ$­Þ~initial threadšª¶J%Ї/usr/local/lib/python2.6/lib-old/pcs­Þ~initial threadšª¶JbЇ¼ ­Þ~initial threadšª¶JnЇà×ÿÿÿ¶'­Þ~initial threadšª¶JyЇ/usr/local/lib/python2.6/lib-old/pcs.so­Þ~initial threadšª¶J‘Ї ­Þ~initial threadšª¶JœÐ‡à×ÿÿÿ¶-­Þ~initial threadšª¶J¨Ð‡/usr/local/lib/python2.6/lib-old/pcsmodule.so­Þ~initial threadšª¶JÀЇ ­Þ~initial threadšª¶JËЇà×ÿÿÿ¶'­Þ~initial threadšª¶JÖЇ/usr/local/lib/python2.6/lib-old/pcs.py­Þ~initial threadšª¶JîЇ ­Þ~initial threadšª¶JùЇà×ÿÿÿ¶(­Þ~initial threadšª¶Jч/usr/local/lib/python2.6/lib-old/pcs.pyc­Þ~initial threadšª¶Jч­Þ~initial threadšª¶J'ч¼à×ÿÿÿ×ÿÿÿ(­Þ~initial threadšª¶J2ч/usr/local/lib/python2.6/lib-dynload/pcs­Þ~initial threadšª¶JIч¼ ­Þ~initial threadšª¶JTчà×ÿÿÿ¶+­Þ~initial threadšª¶J`ч/usr/local/lib/python2.6/lib-dynload/pcs.so­Þ~initial threadšª¶Jxч ­Þ~initial threadšª¶JŒÑ‡à×ÿÿÿ¶1­Þ~initial threadšª¶J™Ñ‡/usr/local/lib/python2.6/lib-dynload/pcsmodule.so­Þ~initial threadšª¶J±Ñ‡ ­Þ~initial threadšª¶J¼Ñ‡à×ÿÿÿ¶+­Þ~initial threadšª¶JÇч/usr/local/lib/python2.6/lib-dynload/pcs.py­Þ~initial threadšª¶Jßч ­Þ~initial threadšª¶Jóчà×ÿÿÿ¶,­Þ~initial threadšª¶Jÿч/usr/local/lib/python2.6/lib-dynload/pcs.pyc­Þ~initial threadšª¶JÒ‡­Þ~initial threadšª¶J#Ò‡¼à×ÿÿÿ×ÿÿÿ*­Þ~initial threadšª¶J.Ò‡/usr/local/lib/python2.6/site-packages/pcs}­Þ~initial threadšª¶JHÒ‡stat[ò‡íAètª¶Jtª¶Jtª¶Jtª¶J­Þ~initial threadšª¶JSÒ‡¼­Þ~initial threadšª¶J]Ò‡¼à×ÿÿÿ Îÿÿÿ6­Þ~initial threadšª¶JhÒ‡/usr/local/lib/python2.6/site-packages/pcs/__init__.py}­Þ~initial threadšª¶JƒÒ‡stat[󇤪¶J”•¶Jtª¶J‘‚Ä”•¶J­Þ~initial threadšª¶JŽÒ‡¼­Þ~initial threadšª¶JÒ‡¼€Óÿÿÿ°Òÿÿÿ3­Þ~initial threadšª¶J¨Ò‡/usr/local/lib/python2.6/site-packages/pcs/__init__­Þ~initial threadšª¶JÀÒ‡¼ ­Þ~initial threadšª¶JÌÒ‡€Óÿÿÿ¶6­Þ~initial threadšª¶J×Ò‡/usr/local/lib/python2.6/site-packages/pcs/__init__.so­Þ~initial threadšª¶JñÒ‡ ­Þ~initial threadšª¶JüÒ‡€Óÿÿÿ¶<­Þ~initial threadšª¶JÓ‡/usr/local/lib/python2.6/site-packages/pcs/__init__module.so­Þ~initial threadšª¶J!Ó‡ ­Þ~initial threadšª¶J,Ó‡€Óÿÿÿ¶6­Þ~initial threadšª¶J8Ó‡/usr/local/lib/python2.6/site-packages/pcs/__init__.py­Þ~initial threadšª¶JRÓ‡­Þ~initial threadšª¶J]Ó‡½ Òÿÿÿ}­Þ~initial threadšª¶JiÓ‡stat[󇤪¶J”•¶Jtª¶J‘‚Ä”•¶J­Þ~initial threadšª¶JsÓ‡½ ­Þ~initial threadšª¶J~Ó‡Îÿÿÿ¶7­Þ~initial threadšª¶JŠÓ‡/usr/local/lib/python2.6/site-packages/pcs/__init__.pyc­Þ~initial threadšª¶J©Ó‡­Þ~initial threadšª¶J´Ó‡½Íÿÿÿ}­Þ~initial threadšª¶J¿Ó‡stat[+ˆ¤0Kª¶Jtª¶Jtª¶JÌtª¶J­Þ~initial threadšª¶JÊÓ‡½ ­Þ~initial threadšª¶JÕÓ‡àË­Þ~initial threadšª¶JïÓ‡Ñò ”•¶Jc @sÌdZdZddkZddkTddkiZddkZddkZd„Zde fd„ƒYZ de fd „ƒYZ d e fd „ƒYZ d e fd „ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZde fd„ƒYZdeefd„ƒYZe eeeeefZde fd„ƒYZdefd„ƒYZd e fd!„ƒYZd"d#d$d%gZd&e fd'„ƒYZd(efd)„ƒYZd*e fd+„ƒYZd,e fd-„ƒYZd.e fd/„ƒYZ d0e fd1„ƒYZ!d2e fd3„ƒYZ"d4e fd5„ƒYZ#d6e fd7„ƒYZ$d8e fd9„ƒYZ%d:e fd;„ƒYZ&d<e&fd=„ƒYZ'd>e&fd?„ƒYZ(d@e&fdA„ƒYZ)dBe&fdC„ƒYZ*dDe*fdE„ƒYZ+dFe*fdG„ƒYZ,dHe+fdI„ƒYZ-dJe*fdK„ƒYZ.dLe&fdM„ƒYZ/dNe/fdO„ƒYZ0dPe/fdQ„ƒYZ1dRe/fdS„ƒYZ2dT„Z3dU„Z4dV„Z5dS(WsÖPCS aka Packet Construction Set PCS is a set of Python modules and objects that make building network protocol testing tools easier for the protocol developer. The core of the system is the pcs module itself which provides the necessary functionality to create classes that implement packets. In PCS every packet is a class and the layout of the packet is defined by a Layout class which contains a set of Fields. Fields can be from 1 to many bits, so it is possible to build packets with arbitrary width bit fields. Fields know about the widths and will throw exceptions when they are overloaded. Every Packet object, that is an object instantiated from a specific PCS packet class, has a field named bytes which shows the representation of the data in the packet at that point in time. It is the bytes field that is used when transmitting the packet on the wire. For more information please see the manual, called pcs, and available in various formats after installation. s4$Id: __init__.py,v 1.9 2006/09/05 07:30:56 gnn Exp $iÿÿÿÿN(t*cCs%t|d„ti|d„|ƒƒS(NcSs#d|itt||iƒƒfS(s%s: %s(tnametreprtgetattr(txty((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytLscSst||iƒS((thasattrR(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRLs(tmapt itertoolstifilter(tobjtattrs((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytattribreprlistKstFieldBoundsErrorcBs eZdZd„Zd„ZRS(spWhen a programmer tries to set a field with an inappropriately sized piece of data this exception is raised.cCs ||_dS(N(tmessage(tselfR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__init__RscCs t|iƒS(N(RR(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__str__Ts(t__name__t __module__t__doc__RR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRNs tFieldcBseZdZdddedd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z hd „Zd „ZeeƒZRS(sñA field is a name, a type, a width in bits, possibly a default value and can be marked as a dicriminator for higher level packet demultiplexing . These classes are used by the packet to define the layout of the data and how it is addressed.ticCs]d|_||_||_||_||_||_|djo d|_n ||_dS(sinitialize a field name - a string name width - a width in bits default - a default value discriminator - is this field used to demultiplex packets ­Þ~initial threadšª¶JûÓ‡­Þ~initial threadšª¶JÔ‡½ Žÿÿÿ}­Þ~initial threadšª¶JÔ‡stat[+ˆ¤0Kšª¶Jtª¶Jtª¶JÌtª¶J­Þ~initial threadšª¶JÔ‡½ ­Þ~initial threadšª¶JÕ‡àË­Þ~initial threadšª¶J(Õ‡ match - a match function used to compare this field with another. iN(tNonetpacketRtwidthtdefaultt discriminatortcomparetvalue(RRRRRR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR_s        cCs d|i|i|i|ifS(s9return an appropriate representation for the Field objects;(RRRR(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__repr__zsc Cs\d}|i}t|ƒ}x(|djo||jo ||joJ||}t||ƒ|?}d|d} || @}||8}d}n¥||joJ||}d|d} t||ƒ| @}||8}d}|d7}nN||jo@d|d} t||ƒ| @}||8}d}|d7}n|||>7}qW||_|||gS(sDecode a field and return the value and the updated current pointer into the bytes array bytes - the byte array for the packet curr - the current byte position in the bytes array byteBR - the number of Bits Remaining in the current byte iiii(RtlentordR( RtbytestcurrtbyteBRt real_valuetfieldBRtlengthtshiftRtmask((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytdecodes8              cCs/|i}x|djo ||jo=||}||8}d|d|>}|||>|@B}Pq ||jo]||}||8}d|d}|||?|@B}|itid|ƒƒd}d}q ||joFd|d}|||@B}|itid|ƒƒd}d}Pq q W||gS(sMencode the a field into the bytes necessary to transmit it as part of a packet bytearray - the array of bytes that will be returned value - the value to encode byte - the byte we are encoding, we can encode partial bytes byteBR - the bits remaining in the current byte being encoded. iiitBi(Rtappendtstructtpack(Rt bytearrayRtbyteR$R&R(R)((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytencode§s2           cCs ||_dS(sSet the value of a field.N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt set_valueÔscCs|iS(N(R(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt get_valueØscCsdS(sBReturn a resonable value to use in resetting a field of this type.i((R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytresetÛscCsX|djp%|djp|d|idjo"tdd|id|f‚ndS(sCheck the bounds of this field.iiis(Value must be between 0 and %d but is %dN(RRR(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytboundsßs  cCs |iƒS(soReturn a shallow copy of a Field; used by copy module. Fields may be copied, they are not immutable.(t __deepcopy__(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__copy__æsc Csš|iƒ}||t|ƒ<|id|id|id|id|id|iƒ|i|_|i|ijp t d‚|i djp t d‚|S( s¸Return a deep copy of a Field; used by copy module. Fields may be copied, they are not immutable; however they always contain integer types which *are* immutable.RRRRRsvalue not c­Þ~initial threadšª¶J4Õ‡ ­Þ~initial threadšª¶JÕ‡àË­Þ~initial threadšª¶J™Õ‡opiedsdangling reference to PacketN( t __class__tidRRRRRRRtAssertionErrorRR(Rtmemotresult((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR6ës     cCs|i|ijS(sþDefault comparison method. lp - packet on left hand side of comparison lf - field in lp being compared rp - packet on right hand side of comparison rf - field in rp being compared This function is installed in Field.compare on assignment. It is declared static to allow folk to override it with lambda functions. The packets are passed so that back-references to other fields in the packet are possible during the match.(R(tlptlftrptrf((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytdefault_compareüs N(RRRRtFalseRRR*R1R2R3R4R5R7R6RAt staticmethod(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRYs   ( -       tFieldAlignmentErrorcBseZdZd„ZRS(sfWhen a programmer tries to decode a field that is not on a byte boundary this exception is raised.cCs ||_dS(s#set the FieldAlignmentError messageN(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRs(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRD st StringFieldcBsPeZdZddd d d„Zd„Zd„Zd„Zd„Zd„Z RS( sàA string field is a name, a width in bits, and possibly a default value. The data is to be interpreted as a string, but does not encode the length into the packet. Length encoded values are handled by the LengthValueField.RicCsTd|_||_||_||_||_|djo d|_n ||_dS(sinitialtize a StringFieldRN(RRRRRRR(RRRRR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRs       cCsd|i|i|ifS(s4return a human readable form of a StringFeild objects/(RRR(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR1scCs|dj o|djo td‚nd|id}||id}ti||||!ƒd}||id7}||_|||gS(seDecode the field and return the value as well as the new current position in the bytes array.is%Strings must start on a byte boundarys%dsiN(RRDRR-tunpackR(RR"R#R$tpackargtendR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR*6s  cCs[|dj o|djo td‚nd|id}|iti||ƒƒ||gS(s7Encode a string field, make sure the bytes are aligned.is%Strings must start on a byte boundarys%dsN(RRDRR,R-R.(RR/RR0R$RG((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR1Cs  cCsdS(sBReturn a resonable value to use in resetting a field of this type.R((R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR4KscCsC|djpt|ƒ|idjotd|id‚ndS(sCheck the bounds of this field.is)Value must be between 0 and %d bytes longN(RR RR(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR5Os'N( RRRR­Þ~initial threadšª¶J¥Õ‡ ­Þ~initial threadšª¶J°Õ‡àË­Þ~initial threadšª¶JÆÕ‡RRR*R1R4R5(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyREs     tLengthValueFieldErrorcBseZdZd„ZRS(sDLengthValue fields only allow access to two internal pieces of data.cCs ||_dS(sset the error messageN(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRWs(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRITstLengthValueFieldcBsŒeZdZd d„Zd„Zd„Zd„Zd„Zd„Z d„Z d„Z d „Z d „Z hd „Zd „ZeeƒZRS(s•A length value field handles parts of packets where a length and value are encoded together, usually used to shove strings into packets. cCs¶d|_||_||_t|tƒptdt|ƒ‚nti |d|ƒt|tƒpt|t ƒoti |d|ƒntdt|ƒ‚|i |i |_ dS(Ns&Length must be of type Field but is %sR'Rs4Value must be of type Field or StringField but is %s( RRRRt isinstanceRRIttypetobjectt __setattr__RER(RRR'RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRds    cCs d|i|i|i|ifS(Ns>R?R@((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRA·sN(RRRRRRRORNR*R1R2R4R5R7R6RARC(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRJ^s        tTypeValueFieldcBszeZdZd d„Zd„Zd„Zd„Zd„Zd„Z d„Z d„Z hd „Z d „Z ee ƒZ RS( sYA type-value field handles parts of packets where a type is encoded before a value. cCs¢d|_||_t|tƒptd||ƒ‚n||_t|tƒpt|tƒo ||_ntd||ƒ‚|i |i |_ ||_ dS(Ns$Type must be of type Field but is %ss4Value must be of type Field or StringField but is %s( RRRRKRRIRLRERRR(RRRLRR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÁs     cCsd|i|i|ifS(Ns/(RRLR(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÎscCs7ti|||ƒ|idj ot|i_ndS(N(RMRNRRRPt_TypeValueField__needencode(RRR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRNÑscCs[|ii|||ƒ\|i_}}|ii|||ƒ\|i_}}t||gS(N(RLR*R(RR"R#R$((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR*Ös''cCsX|ii||ii||ƒ\}}|ii||ii||ƒ\}}||gS(N(RLR1R(RR/RR0R$((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR1Ûs''cCsdS(sBReturn a resonable value to use in resetting a field of this type.R((R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR4àscCsS|djp"t|ƒd|iddjo tdd|idd‚ndS(sCheck the bounds of this field.iiis)Value must be between 0 and %d bytes longN(RR t valuewidthRR(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR5äs "c Cs4|id|id|id|id|iƒ}|S(sŒReturn a shallow copy of a TypeValueField; used by copy module. A shallow copy just makes references to these Fields in the copy.RRLRR(R8RRLRR(RR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR7ës    c Csfddkl}|id|id||i|ƒd||i|ƒd|iƒ}||t|ƒ<|S(svReturn a deep copy of a TypeValueField; used by copy module. A deep copy copies all of the embedded Fields.iÿÿÿÿ(RRRRLRR(RSRRR8RRLRRR9(RR;RRR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR6ôs cCs|i|ijS(sDefault comparison method.(R(R=R>R?R@((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRAÿsN(RRRRRRRNR*R1R4R5R7R6RARC(((s6/usr/local/lib/python­Þ~initial threadšª¶JøÕ‡ ­Þ~initial threadšª¶JÖ‡àË­Þ~initial threadšª¶JÖ‡2.6/site-packages/pcs/__init__.pyRT½s       tTypeLengthValueFieldcBs€eZdZeed d„Zd„Zd„Zd„Zd„Z d„Z d„Z d„Z hd „Z d „ZeeƒZRS( skA type-length-value field handles parts of packets where a type is encoded before a length and value. cCsëd|_||_t|tƒptd||ƒ‚n||_t|tƒptd||ƒ‚n||_t|tƒpt|tƒo ||_ ntd||ƒ‚|i |i |i |_ ||_ ||_ ||_ dS(Ns$Type must be of type Field but is %ss&Length must be of type Field but is %ss4Value must be of type Field or StringField but is %s(RRRRKRRIRLR'RERRt inclusivetbytewiseR(RRRLR'RRXRYR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR s        cCsd|i|i|ifS(Ns7(RLR'R(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRscCs7ti|||ƒ|idj ot|i_ndS(N(RMRNRRRPt!_TypeLengthValueField__needencode(RRR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRN!scCs‚|ii|||ƒ\|i_}}|ii|||ƒ\|i_}}|ii|||ƒ\|i_}}t||gS(N(RLR*RR'(RR"R#R$((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR*&s'''cCst|itƒo|ii|i_nt|iƒd|i_|itjo&|ii|ii|ii7_n|i tjo|iid:_n|ii ||ii||ƒ\}}|ii ||ii||ƒ\}}|ii ||ii||ƒ\}}||gS(sEncode a TypeLengthValue field.i( RKRRRR'R RXRPRLRYR1(RR/RR0R$((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR1,s&'''cCsdS(sBReturn a resonable value to use in resetting a field of this type.R((R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR4CscCsS|djp"t|ƒd|iddjo tdd|idd‚ndS(sCheck the bounds of this field.iiis)Value must be between 0 and %d bytes longN(RR t lengthwidthRR(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR5Gs "cCsO|id|id|id|id|id|id|id|iƒ}|S(s¨Return a shallow copy of a TypeLengthValueField; used by copy module. A shallow copy just makes references to these Fields in the copy.RRLR'RRXRYR(R8RRLR'RRXRYR(RR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR7Ns      cCsŠddkl}|id|id||i|ƒd||i|ƒd||i|ƒd|id|id |i ƒ}||t |ƒ<|S( s‡Return a deep copy of a TypeLengthValueField; used by copy module. A deep copy copies all of the embedded Fields.iÿÿÿÿ(RRRRLR'RRXRYR( RSRRR8RRLR'RRXRYRR9(RR;RRR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR6\s   cCs|i|ijS(sDefault comparison method.(R(R=R>R?R@((s6/usr/local/lib/python2.6/site-packages/pc­Þ~initial threadšª¶JWÖ‡ ­Þ~initial threadšª¶JbÖ‡àË­Þ~initial threadšª¶JsÖ‡s/__init__.pyRAksN(RRRRPRRRRNR*R1R4R5R7R6RARC(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRWs         t CompoundFieldcBseZdZRS(s*A compound field may contain other fields.(RRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR\rstOptionListErrorcBs eZdZd„Zd„ZRS(seWhen a programmer tries to append to an option list and causes an error this exception is raised.cCs ||_dS(N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRyscCs t|iƒS(N(RR(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR{s(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR]us tOptionListFieldcBsÚeZdZdgdd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zd„Zd„Zd„Zhd„Zd„ZeeƒZRS(sdA option list is a list of Fields. Option lists inhabit many protocols, including IP and TCP.icCs‚ti|ƒd|_||_||_g|_|gjo%x"|D]}|ii|ƒqEWn||_||_ ||_ dS(sIniitialize an OptionListField.N( tlistRRRRRt_optionsR,RRR(RRRt option_listRtoption((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR‚s        cCs t|iƒS(N(R R`(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRO‘scCs d|_|S(Ni(tindex(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__iter__”s cCsft|iƒ}|djo t‚n|i|jo t‚n|i|ii}|id7_|S(s;Option lists return a pair of (value, option) when iteratedii(R R`t StopIterationRcR(RR'tretval((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytnext˜s   cCs°|djotSt|iƒ}|t|iƒjotSxmt|ƒD]_}|i|}t|tƒo#|i|i|ijotSqI||i|jotSqIWtS(sŠTest two option lists for equality. Two option lists are equal if and only if they have the same options and values.N( RRBR R`txrangeRKRRRP(RtotherR'titf((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__eq__£s     cCs|i|ƒ S(s$test two option lists for inequality(Rl(RRi((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__ne__ºscCs |iƒS(N(R(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR¾scCs¦d}d}x‰|iD]~}t|tƒo|d|i|f7}n|d|i|if7}|t|iƒdjoPn|d7}|d7}qW|d7}|S(s#return a pretty printed option listt[is[Field: %s, Value: %s]is, t](R`RKR\RRR (RRfRcRb((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÁs   cCs|djp|t|iƒjotd|‚nÙt|tƒokt|ƒdjo td‚nt|dtƒp td‚n|d|i|<|d|i|_d­Þ~initial threadšª¶J~Ö‡ ­Þ~initial threadšª¶J‰Ö‡àË­Þ~initial threadšª¶J™Ö‡St|tƒo)|i|i|iƒ||i|R?R@((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRA7sN(RRRRRRORdRgRlRmRRRrRsR5R2RtR,R1R*R4R7R6RARC(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR^~s,              tLayoutDiscriminatorErrorcBs eZdZd„Zd„ZRS(sjWhen ­Þ~initial threadšª¶J¥Ö‡ ­Þ~initial threadšª¶J°Ö‡àË­Þ~initial threadšª¶J¿Ö‡a programmer tries to set more than one field in a Layout as a discriminator an error is raised.cCs ||_dS(N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyREscCs t|iƒS(N(RR(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRGs(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRwAs tLayoutcBs#eZdZdd„Zd„ZRS(sêThe layout is a special attribute of a Packet which implements the layout of the packet on the wire. It is actually a list of Fields and is implemented as a descriptor. A layout can only be set or get, but never deleted.cCs|iS(sreturn the Layout(t_layout(RR ttyp((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__get__TscCso||_x_|iD]T}t|dƒ p|idjo|iƒ|i|is, (RR—RˆR RyRd(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR`s cCs |iƒS(s Print the packet in line format.(R(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytprintlniscCsgd}t|dƒo|d|i7}nx5|iD]*}|d|i|i|iif7}q5W|S(s5Pretty print, with returns, the fields of the packet.RR—s%s s%s %s (RR—RyRR‡R(RRfR}((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRms  cCs t|iƒS(s6Return the count of the number of bytes in the packet.(R R"(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyROzscCsÖt|tƒp ti‚n|idjoP|iƒ}|itj o|i |ƒn|i |ƒ||_||_nV|i}t|t ƒp ti‚n|i ||ƒt jo ti‚n||_|S(s2/ operator: Insert a packet after this packet in a chain. If I am not already part of a chain, build one. If the discriminator field in this packet has not been explicitly initialized, either by assignment or by constructor keyword arguments, then attempt to initialize it based on the type of the packet being appended. The packet being appended will have its head pointer overwritten to point to the chain it is being appended to. The head of the chain is always returned.N(RKRƒt exceptionst TypeErrorR‚RtchainR‰RPt rdiscriminateR,tChaint insert_afterRBRp(RRthead((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt__div__~s          cCs |iƒS(smReturn a shallow copy of a Packet; used by copy module. This is always implemented as a deep copy.(R6(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR7šscCsgddkl}|iƒ}x4|iD])}||i|i|ƒ|i|i  +         -      RcBsæeZdZgd„Zd„Z­Þ~initial threadšª¶Jhׇ ­Þ~initial threadšª¶JsׇàË­Þ~initial threadšª¶J‰×‡d„Zd„Zd„Zed„Z d„Z hd„Z d „Z ed „Z d „Zd „Zed „Zd„Zd„Zd„Zd„Zd„Zed„Zd„Zd„Zd„ZRS(s{A chain is simply a list of packets. Chains are used to aggregate related sub packets into one chunk for transmission.cCsAti|ƒ||_x|iD]}||_q W|iƒdS(siinitialize a Chain object packets - an optional list of packets to add to the new Chain N(R_RtpacketsR‚R1(RR®tp((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR&s     cCsnt|iƒt|iƒjotSt|iƒ}x4t|ƒD]&}|i||i|jotSq@WtS(s–test two Chain objects for equality Two chains are equal iff they have the same packets and their packets have the same data in them.(R R®RBRhRP(RRiR'Rj((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRl4s  cCs|i|ƒ S(s%test two Chain objects for inequality(Rl(RRi((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRmAscCs2d}x%|iD]}|d|iƒ7}qW|S(sreturn a pretty printed ChainRs%s (R®R(RRfR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyREs  cCs |iiƒS(N(R®R(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRNscCswt|tƒp ti‚n|tjo3|iditj o|idi|ƒq]n|i|ƒ||_ |S(s/ operator: Append a packet to the end of a chain. The packet's head pointer will be overwritten to point to this chain. The default behaviour is to fill out the discriminator field of the packet in front of the new tail packet.iÿÿÿÿ( RKRƒR™RšRPR®R‰RœR,R‚(RRRœ((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR Rs    cCs |iƒS(slReturn a shallow copy of a Chain; used by copy module. This is always implemented as a deep copy.(R6(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR7bscCsyddkl}|igƒ}||t|ƒØ‡ ­Þ~initial threadšª¶JJ؇àË­Þ~initial threadšª¶J`؇s this packet, and its index in the chain, as a tuple. If the 'adjacent' argument is True, then the packet immediately preceding 'packet' must be an instance of type. Helper method used by Internet transport protocols.iiiN(NN(NN(R¸RRPtmaxtreversedR®RK(RRR»tadjacentR¶tlowerR¯((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytfind_precedingês   cCs(x!t|iƒD]}|iƒqWdS(sTCompute and store checksums for all packets in this chain, taking encapsulation into account. By default the packets are enumerated in reverse order to how they appear on the wire. This is how IETF-style protocols are normally dealt with; ITU-style protocols may require other quirks.N(R½R®R¦(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytcalc_checksumsþs cCs(x!t|iƒD]}|iƒqWdS(smCompute and store length fields for all packets in this chain, taking encapsulation into account. N(R½R®R§(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt calc_lengths scCs"|iƒ|iƒ|iƒdS(s?Convenience method to calculate lengths, checksums, and encode.N(RÂRÁR1(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytfixups  (RRRRRlRmRRRPR R7R6R,RžRµR“R–R1R*R¸RºR´RÀRÁRÂRÃ(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR"s.              tConnNotImpErrorcBseZdZd„ZRS(sìCalling a method that is not implemented raises this exception. The base class, and some of the derived classes do not implement every moethod that could be. This exception is meant to catch and report thos instances. cCs ||_dS(N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRs(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÄstEOFErrorcBseZdZdd„ZRS(sPIf the I/O handle was closed, or end of file seen, raise this exception. s End of filecCs ||_dS(N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR%s(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÅ!stLimitReachedErrorcBseZdZdd„ZRS(s>If a packet input threshold is reached, raise this exception. s Limit reachedcCs ||_dS(N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR+s(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÆ(st TimeoutErrorcBseZdZdd„ZRS(sWIf a possibly blocking read operation times out, this exception will be raised. s Timed outcCs ||_dS(N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR2s(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÇ.st UnpackErrorcBseZdZd„ZRS(s-Error raised when we fail to unpack a packet.cCs ||_dS(N(R(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR7s(RRRR((­Þ~initial threadšª¶Jl؇ ­Þ~initial threadšª¶Jw؇àË­Þ~initial threadšª¶JŒØ‡(s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÈ5stEOFcBseZdZd„ZRS(sDThis type allows end-of-file to be matched as a pattern by expect().cCsdS(N((R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR<s(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÉ:stTIMEOUTcBseZdZd„ZRS(sAThis type allows timeouts to be matched as a pattern by expect().cCsdS(N((R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRAs(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÊ?stLIMITcBseZdZd„ZRS(s;This type allows 'limit reached' to be matched by expect().cCsdS(N((R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRFs(RRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRËDst ConnectorcBs°eZdZd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z d „Z d „Z d „Zd „Zd„Zd„Zd„Zgddd„ZRS(sãConnectors are a way of have a very generic socket like mechanism over which the packets can be sent. Unlike the current split between sockets, which work OK down to almost the RAW layer, and low level stuff like pcap and bpf, connectors will are a unifying mechanism so you can write packets over any of the available APIs and the connector will do the right thing. The Connector class is a virtual base class upon which all the real classes are based.cCsd|_d|_dS(N(RR“t match_index(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRTs cCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytacceptZscCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytbind]scCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytconnect`scCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytlistencscCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytreadfscCs td‚dS(s_Poll the underlying I/O layer for a read. Return TIMEOUT if the timeout was reached.sCannot use base classN(RÄ(Rttimeout((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt poll_readiscCs td‚dS(s•Read a packet from the underlying I/O layer, and return an instance of a class derived from pcs.Packet appropriate to the data-link or transport layer in use. If the Connector has multiple data-link layer support, then the type returned by this method may vary. If the underlying packet parsers throw an exception, it will propagate here. sCannot use base classN(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt read_packetnscCs|iƒ}|iƒS(sâRead the next available packet and attempt to decapsulate all available layers of encapsulation into Python objects. If the underlying packet pars­Þ~initial threadšª¶J˜Ø‡ ­Þ~initial threadšª¶J¤Ø‡àË­Þ~initial threadšª¶J´Ø‡ers throw an exception, it will propagate here.(RÕR›(RR¯((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt read_chainxs cCs|g}|djp |djo d}nxKt|ƒD]=}|iƒ}|dj o|iƒ}|i|ƒq7Pq7W|S(sTry to read at most n packet chains from the underlying I/O layer. If n is None or 0, try to read exactly one packet. Connectors with their own buffering semantics should override this method (e.g. PcapConnector). Used by expect().iiN(RRhRÕR›R,(RR¶R<RjR¯tc((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyttry_read_n_chains€s     cCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytwrite‘scCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytsend”scCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytsendto—scCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytrecvšscCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytrecvfromscCs td‚dS(NsCannot use base class(RÄ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytclose sc Csyddkl}|ƒ}|}|}|}d|_d|_x5to-|i|ƒ} |dj o|ƒ} | |}| }nt|ƒ} |dj od| ||joSxFt| ƒD]8} t|| t ƒo|| g|_| |_| Sq·Wt ‚nt| t ƒo|djoq@q%nt| t ƒoSxFt| ƒD]8} t|| t ƒo|| g|_| |_| SqBWt ‚n|i |ƒ} d}g}d}xÎtt| ƒƒD]º} | | }|dj o|d8}nx`t| ƒD]R}||}t|tƒo2|i|ƒo"|i|ƒ|}| d}PqôqôW|dj p|dj o|djoPq¼q¼W|dj o|||}xXt|t| ƒƒD]A} | | }t|tƒo!|i|ƒo|i|ƒq§q§W||_||_|S|dj o`|djoSxFt| ƒD]8} t|| tƒo|| g|_| |_| Sq*Wt‚q@q@WdS(s*Read from the Connector and return the index of the first pattern which matches the input chain; otherwise, raise an exception. On return, the matches property will contain a list of matching packet chain(s). There may be more than one match if a live capture matches more than one before the loop exits. * If the 'limit' argument is set, raise an exception after 'limit' packets have been read, regardless of match. * If 'timeout' is set, raise an exception after the timeout expires. This is only supported if the underlying Connector fully implements non-blocking I/O. The syntax is intentionally similar to that of pexpect: * If any of EOF, LIMIT or TIMEOUT are specified, the exceptions are not raised but are instead matched as patterns. * If a Chain is specified, it is matched against the chain using the Chain.match() method. * If neither a timeout or a limit is specified, or an EOF was not encountered, this function may potentially block forever. * NOTE: Packets can no longer be specified on their own as filters. TODO: Make this drift and jitter robust (CL­Þ~initial threadšª¶JÀ؇ ­Þ~initial threadšª¶JËØ‡àË­Þ~initial threadšª¶JáØ‡OCK_MONOTONIC).iÿÿÿÿ(ttimeiiN(RßRR“RÍRPRÔR RhRKRÊRÇRÉRÅRØRR,RËRÆ(RtpatternsRÓtlimitRßtstarttthent remainingtdeltaR<tnowR'Rjtchainst next_chainR“RÍR×tjtfilter((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytexpect£s’                                     N(RRRRRÎRÏRÐRÑRÒRÔRÕRÖRØRÙRÚRÛRÜRÝRÞRRë(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÌIs$                t PcapConnectorcBsËeZdZddedd„Zd„Zd„Zd„Zd„Z dd„Z d „Z d „Z d „Z gddd „Zd „Zd„Zd„Zd„Zd„Zd„Zd„ZeeƒZRS(s³A connector for protocol capture and injection using the pcap library The Pcap connector looks like all the rest of the connectors for PCS with the differnece that it provides direct network access and bypasses all the protocol stacks on a system. The usual precautions about routing, framing and the like apply so do not use this connector if you're not prepared to do all the protocol work on your own. iÿÿiôcCsŒtt|ƒiƒyti||||ƒ|_Wn ‚nX|ii|_|ii|_|iiƒ|_|ii t ƒt |_ dS(s$initialize a PcapConnector object name - the name of a file or network interface to open snaplen - maximum number of bytes to capture for each packet promisc - boolean to specify promiscuous mode sniffing timeout_ms - read timeout in milliseconds N( tsuperRìRtpcaptfiletdlofft setfiltertdatalinktdlinkt setnonblockRBtis_nonblocking(RRtsnaplentpromisct timeout_ms((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR/s cCs|iiƒdS(s_read a packet from a pcap file or interface returns the packet as a bytearray i(RïRg(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÒGscCs|iiƒdS(s+recv a packet from a pcap file or interfacei(RïRg(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÜNscCs|iiƒdS(s/recvfrom a packet from a pcap file or interfacei(RïRg(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÝRscCs|ii|ƒS(sSet the pcap direction.(Rït setdirection(Rtinout((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRùVscCsddkl}|iiƒ}|ip|iitƒn||ggg|ƒ}|ip|iitƒn||djotƒSdS(s_Poll the underlying I/O layer for a read. Return TIMEOUT if the timeout was reached.iÿÿÿÿ(tselectiN( RûRïtfilenoRõRôRPRBRÊR(RRÓRûtfdR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÔZs  cCs1|iiƒ\}}|i||i|i|ƒS(N(RïRgRFRóRð(RR¤R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÕjscCs |iƒS(N(RÕ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytreadpktnscCs£|djp |djo d}ng}g}d„}|ii|||ƒxM|D]E}|i|d|i|­Þ~initial threadšª¶JƒÙ‡ ­Þ~initial threadšª¶JÙ‡àË­Þ~initial threadšª¶JŸÙ‡i|dƒ}|iƒ}|i|ƒqVW|S(sŸTry to read at most n packet chains from the pcap session. Used by Connector.expect() to do the right thing with buffering live captures.iiÿÿÿÿcWs!|d}|i||fƒdS(Ni(R,(ttsR¯targstltp((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pythandlerzs iN(RRïtdispatchRFRóRðR›R,(RR¶R<RRttpR¯R×((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRØrs  & cCsy|i}|tjo|iitƒt|_nti||||ƒ}|tjo|iitƒt|_n|S(s"PcapConnector needs to override expect to set it up for non-blocking I/O throughout. We do this to avoid losing packets between expect sessions. Typically we would also set up pcap filter programs here if performing potentially expensive matches.(RõRBRïRôRPRÌRë(RRàRÓRát oldnblockR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRë…s     cCs|ii||ƒS(sxWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object (Rïtinject(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÙ•scCs|ii||ƒS(swWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object(RïR(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÚœscCs|ii||ƒS(swWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object(RïR(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÛ¢scCsmddk}ddk}|tijo|ii||ƒS|tijo|ii||ƒStd‚dS(sÒCreate a Packet from a string of bytes. packet - a Packet object dlink - a data link layer as defined in the pcap module dloff - a datalink offset as defined in the pcap module iÿÿÿÿNsCould not interpret packet(tpackets.ethernettpackets.localhostRît DLT_EN10MBtethernettDLT_NULLt localhostRÈ(RRRóRðR¤R®((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRF¨s  cCs|iiƒdS(s!Close the pcap file or interface.N(RïRÞ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÞ¹scCs=ddkl}t||ƒp td‚n|ii|ƒS(Niÿÿÿÿ(tprogramsnot a BPF program(tpcs.bpfR RKt ValueErrorRït setbpfprogram(RtprogR ((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytset_bpf_program½s cCs0ddkl}l}l}l}l}l}t|tƒpt ‚d}|ƒ}x6|i D]+} x"| i D]} | i | i } t| tƒoä| i| ijoÑ| itjoÁ| iddjo­| idjo|ii||d?ƒƒn]| idjo|ii||d?ƒƒn/| idjo|ii||d?ƒƒn|ii|dd| iƒƒn|| i7}qnWq^W|ii|dƒƒ|ii|dƒƒt|iƒd } d} xW|iD]L}| d 7} t||ƒo,| | d jp t d ‚| | |_qÜqÜW|S( s;Given a filter chain c, create a simple BPF filter program.iÿÿÿÿ(R tldwtldbtldhtjeqtretiiiii i`iiÿsRelative branch overflow.(RR R­Þ~initial threadšª¶J«Ù‡ ­Þ~initial threadšª¶J¶Ù‡àË­Þ~initial threadšª¶JÆÙ‡RRRRRKRR:R®RyR‡RRRRARRPRt instructionsR,RR tjf(R×R RRRRRtfoffRR¯R’RktjfabstiiRj((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytmake_bpf_programÌs>.   $#  N(RRRRRPRRÒRÜRÝRùRÔRÕRþRØRëRÙRÚRÛRFRÞRRRC(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRì$s(                  %tPcapDumpConnectorcBsAeZdZddd„Zd„Zd„Zd„Zd„ZRS(s8A connector for dumping packets to a file for later re-use. The PcapDump connector allows the programmer to write libpcap compatible files full of packets. Unlike the PcapConnector it does not alloww the programmer to read from a dump file, for that the PcapConnector class should be used. c Cs[ddkl}y|d|d|ƒ|_Wn ‚nX|ii|_|ii|_dS(s initialize a pcap dump connectoriÿÿÿÿ(RîtdumpfiletdumptypeN(RîRïRðRñ(RRR Rî((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRüscCsMt|ƒtjo*dt|ƒ}ti||ƒd}n|ii|ƒS(swrite a packet to the dumpfiles%dsi(RLtbufferR R-RFRïtdump(RRRG((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÙscCs|ii|ƒS(s?send a packet to the dumpfile calls the write() method(RïR"(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÚscCs|ii|ƒS(sAsendto a packet to the dumpfile calls the write() method(RïR"(RRtheader((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÛscCs|iiƒdS(sclose the dumpfileN(Rït dump_close(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÞsN( RRRRRRÙRÚRÛRÞ(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRós    t TapConnectorcBsÅeZdZd„Zd„Zd„Zd„Zd„Zd„Zd„Z d„Z d „Z dd „Z d „Zgddd „Zd „Zd„Z d„Z d„Zd„Zd„Zd„ZRS(séA connector for capture and injection using the character device slave node of a TAP interface. Like PcapConnector, reads are always blocking, however writes may always be non-blocking. The underlying I/O is non-blocking; it is hard to make it work with Python's buffering strategy for file(), so os-specific reads/writes are used. No filtering is currently performed, it would be useful to extend pcap itself to work with tap devices. cCsUddk}ddkl}l}t|_y|i||ƒ|_Wn ‚nXdS(shinitialize a TapConnector object name - the name of a file or network interface to open iÿÿÿÿN(t O_NONBLOCKtO_RDWR(tosR&R'RBRõtopenRü(RRR(R&R'((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR+s  cCs |iƒS(sUread a packet from a tap interface returns the packet as a bytearray (t blocking_read(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÒ7scCs |iƒS(s"recv a packet from a tap interface(R*(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.p­Þ~initial threadšª¶JÑÙ‡ ­Þ~initial threadšª¶JÜÙ‡àË­Þ~initial threadšª¶JêÙ‡yRÜ=scCs |iƒS(s&recvfrom a packet from a tap interface(R*(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÝAscCs|iƒ}tii|ƒS(s\Read a packet from a pcap file or interfaces returning an appropriate packet object.(R*R®R (RR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÕEs cCs |iƒS(N(RÕ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRþKscCs |i|ƒS(sWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object (tblocking_write(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÙOscCs |i|ƒS(svWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object(R+(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÚUscCs |i|ƒS(svWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object(R+(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÛZscCsddkl}|iiƒ}|ip|iitƒn||ggg|ƒ}|ip|iitƒn||djotƒSdS(s_Poll the underlying I/O layer for a read. Return TIMEOUT if the timeout was reached.iÿÿÿÿ(RûiN( RûRïRüRõRôRPRBRÊR(RRÓRûRýR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÔ`s  c CsÎddkl}g}g}to|i o dGHn|ƒ}x?t|ƒD]1}|iƒ}|djoPn|i|ƒqMWxE|D]=}|i||i|i |ƒ}|i ƒ} |i| ƒq‰W|S(söTry to read as many packet chains from the tap device as are currently available. Used by Connector.expect() to do the right thing with buffering live captures. Note that unlike pcap, timestamps are not real-time.iÿÿÿÿ(Rßs6WARNING: TapConnector.try_read_n_chains w/o O_NONBLOCKN( Rßt __debug__RõRht try_read_oneRR,RFRóRðR›( RR¶RßR<tlpbRÿRjtpbR¯R×((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRØps$      cCsb|i}|tjo|itƒt|_nti||||ƒ}|i|ƒ||_|S(sNTapConnector needs to override expect just like PcapConnector does.(RõRBRôRPRÌRë(RRàRÓRáRR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRë‡s      cCsddkl}ddkl}l}l}|ti|ƒ}||@|j|jo7||N}|ti||ƒdjo td‚qŒn|S(s>Set the non-blocking flag. Return the value of the file flags.iÿÿÿÿ(R&(tfcntltF_SETFLtF_GETFLR0(R(R&R0R1R2RRütOSError(tenabledR&R0R1R2tflags((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRô–s cCs|ii||ƒS(syWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packet object(RïR(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÙ¡scCs|ii||ƒS(swWrite a packet to a pcap file or network interface. bytes - the bytes of the packet, and not the packe­Þ~initial threadšª¶J*Ú‡ ­Þ~initial threadšª¶J6Ú‡àË­Þ~initial threadšª¶JEÚ‡t object(RïR(RRR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÚ¦scCs`|i}|tjo$|itƒt|_tdƒnt|ƒ}|i|ƒ||_|S(s2Block until the next packet arrives and return it.N(RõRPtsetnonblockingRBRÔRR-(RRR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR*¬s       c Cs§ddk}ddk}ddk}ddkl}yb|iddgƒ}|i|i||ƒ}|iƒ}|djodS|i |i|ƒSWn ‚nXdS(sZLow-level non-blocking read routine, tries to read the next frame from the tap.iÿÿÿÿN(tFIONREADRji( tarrayR0R(ttermiosR7tioctlRütpopRRÒ(RR8R0R(R7tbuftstqbytes((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR-ºs     cCskddk}|i}|tjo|itƒt|_n|i|i|ƒ}|i|ƒ||_|S(Niÿÿÿÿ(R(RõRPR6RBRÙRü(RR"R(RR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR+Ìs       cCs ddk}|i|iƒdS(Niÿÿÿÿ(R(RÞRü(RR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÞÙs N(RRRRRÒRÜRÝRÕRþRÙRÚRÛRRÔRØRëRôR*R-R+RÞ(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR% s(                t IP4ConnectorcBszeZdZd d„Zd„Zd„Zd„Zdd„Zdd„Z dd„Z dd „Z dd „Z d „Z RS( sBase class for all IPv4 connectors. This class implements all the necessary functions for a plain IPv4 based connector. In particular the data access methods, such as read, write, etc. likely do not need to be overridden by the sub classes. cCs*yttttƒ|_Wn ‚nXdS(sinitialize an IP4ConnectorN(tsockettAF_INETtSOCK_RAWt IPPROTO_IPRï(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRåscCs|ii|ƒS(s!connect to a foreign IPv4 address(RïRÐ(Rtaddress((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÐìscCs|ii|ƒS(sread data from an IPv4 socket(RïRÜ(RR ((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÒðscCs|iiƒ}tii|ƒS(N(RïRÒR®tipv4(RR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÕôsicCs|ii||ƒS(srecv data from an IPv4 socket(RïRÜ(RR R5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÜøscCs|ii||ƒS(s!recvfrom data from an IPv4 socket(RïRÝ(RR R5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÝüscCs|ii||ƒS(swrite data to an IPv4 socket(Rïtsendall(RRR5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÙ scCs|ii||ƒS(ssend data to an IPv4 socket(RïRÚ(RRR5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÚ scCs|ii|||ƒS(ssendto data to an IPv4 socket(RïRÛ(RRtaddrR5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÛ sc­Þ~initial threadšª¶JQÚ‡ ­Þ~initial threadšª¶J\Ú‡àË­Þ~initial threadšª¶JkÚ‡Cs|iiƒdS(sclose an IPv4 ConnectorN(RïRÞ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÞ sN(RRRRRRÐRÒRÕRÜRÝRÙRÚRÛRÞ(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR?Ýs         t UDP4ConnectorcBseZdZddd„ZRS(s%A connector for IPv4 UDP sockets c Csoyttttƒ|_Wn ‚nX|dj o8|dj o+y|ii||fƒWqk‚qkXndS(sˆinitialize a UDPv4 connector address - an optional address to connect to port - an optional port to connect to N(R@RAt SOCK_DGRAMt IPPROTO_UDPRïRRÐ(RRDtport((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR sN(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRH st TCP4ConnectorcBseZdZddd„ZRS(s]A connector for IPv4 TCP sockets The TCP4Connector implements a IPv4 TCP connection c Csoyttttƒ|_Wn ‚nX|dj o8|dj o+y|ii||fƒWqk‚qkXndS(s2initialize a TCP4Connector class for TCP over IPv4N(R@RAt SOCK_STREAMt IPPROTO_TCPRïRRÐ(RRGRK((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR+ sN(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRL% stUmlMcast4ConnectorcBsMeZdZdd„Zd„Zd„Zdd„Zd„Zdd„Z RS( s³A connector for hooking up to a User Mode Linux virtual LAN, implemented by Ethernet frames over UDP sockets in a multicast group. Typically used for interworking with QEMU. See: http://user-mode-linux.sourceforge.net/old/text/mcast.txt No additional encapsulation of the frames is performed, nor is any filtering performed. Be aware that this encapsulation may fragment traffic if sent across a real LAN. The multicast API is being somewhat abused here to send and receive the session on the same socket; generally apps shouldn't bind to group addresses, and it's not guaranteed to work with all host IP stacks. c CsTddk}ddk}ddkl}ddkl}l}|djo d}nyî||_t|ƒ|_t t t t ƒ|_ |i|i |ƒ} | |O} |i|i || ƒ|i ittdƒ|i ittdƒt|iƒ} tid| t|ƒƒ} |i itt| ƒ|i i|i|ifƒWn ‚nXdS(sàinitialize a UML Mcast v4 connector group - the multicast group to join port - the UDP source/destination port for the session ifaddr - optionally, the interface upon which to join the group. iÿÿÿÿN(R&(R2R1s 127.0.0.1is!LL(R(R0R&R2R1RtgrouptintRKR@RARIRJRït setsockoptt SOL_SOCKETt SO_REUSEADDRRCtIP_MULTICAST_LOOPt inet_atolR-R.tIP_ADD_MEMBERSHIPRÏ( RRPRKtifaddrR(R0R&R2R1R5tgaddrtmreq((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRG s*       cCs|iƒ}tii|ƒS(N(R*R®R (RR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÕh s cCs |iƒS(N(RÕ(R((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRþl scCsTddkl}|iiƒ}||ggg|ƒ}||djotƒSdS(Niÿÿÿÿ(Rûi(RûRï­Þ~initial threadšª¶JwÚ‡ ­Þ~initial threadšª¶J‚Ú‡àË­Þ~initial threadšª¶J‘Ú‡RüRÊR(RRÓRûRýR<((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÔp s cCs/ddk}tdƒ|i|iiƒdƒS(NiÿÿÿÿiÞ(R(RÔRRÒRïRü(RR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR*x s  icCs"|ii|||i|ifƒS(swrite data to an IPv4 socket(RïRÛRPRK(RRR5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÙ sN( RRRRRRÕRþRÔR*RÙ(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRO8 s  !    tSCTP4ConnectorcBseZdZddd„ZRS(s_A connector for IPv4 SCTP sockets The TCP4Connector implements a IPv4 SCTP connection c Csoyttttƒ|_Wn ‚nX|dj o8|dj o+y|ii||fƒWqk‚qkXndS(s3initialize a SCTP4Connector class for TCP over IPv4N(R@RARMt IPPROTO_SCTPRïRRÐ(RRGRK((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRŠ sN(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR[„ st IP6ConnectorcBs}eZdZd d„Zd„Zd„Zdd„Zdd„Zdd„Zdd„Z dd „Z dd „Z d „Z RS( sBase class for all IPv6 connectors. This class implements all the necessary functions for a plain IPv6 based connector. In particular the data access methods, such as read, write, etc. likely do not need to be overridden by the sub classes. cCs*yttttƒ|_Wn ‚nXdS(s4initialize an IPPConnector class for raw IPv6 accessN(R@tAF_INET6RBRCRï(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRŸ scCs|ii|ƒS(sread from an IPv6 connection(RïRÜ(RR ((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÒ¦ scCs|iiƒ}tii|ƒS(N(RïRÒR®tipv6(RR"((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÕª sicCs|ii||ƒS(srecv data from an IPv4 socket(RïRÜ(RR R5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÜ® scCs|ii||ƒS(srecv from an IPv6 connection(RïRÜ(RR R5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRܲ scCs|ii||ƒS(sreadfrom on an IPv6 connection(RïRÝ(RR R5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRݶ scCs|ii||ƒS(swrite to an IPv6 connection(RïRF(RRR5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÙº scCs|ii||ƒS(ssend to an IPv6 connection(RïRÚ(RRR5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÚ¾ scCs|ii|||ƒS(ssendto to an IPv6 connection(RïRÛ(RRRGR5((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÛ scCssddk}|idƒ}|id|ƒ}|iittdƒ|iittdƒ|iitt|ƒdS(s%set IP6 connector into multicast modeiÿÿÿÿNslibc.sotif_nametoindexii( tdlR)tcalltsockRRt IPPROTO_IPV6tIPV6_MULTICAST_LOOPtIPV6_MULTICAST_HOPStIPV6_MULTICAST_IF(RtifaceRat­Þ~initial threadšª¶JœÚ‡ ­Þ~initial threadšª¶J§Ú‡àË­Þ~initial threadšª¶J·Ú‡_libctifn((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytmcastÆ s  N( RRRRRRÒRÕRÜRÝRÙRÚRÛRk(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyR]— s         t UDP6ConnectorcBseZdZdd„ZRS(s!A connector for IPv6 UDP sockets c Csoyttttƒ|_Wn ‚nXtdj o8tdj o+y|iittgƒWqk‚qkXndS(sinitialize a UDPv6 connectorN( R@R^RIRJRïRDRRKRÐ(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRÔ sN(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRlÑ st TCP6ConnectorcBseZdZdd„ZRS(s]A connector for IPv4 TCP sockets The TCP4Connector implements a IPv4 TCP connection c Csoyttttƒ|_Wn ‚nXtdj o8tdj o+y|iittgƒWqk‚qkXndS(sinitialize a TCPv6 connectorN( R@R^RMRNRïRDRRKRÐ(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRç sN(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRmá stSCTP6ConnectorcBseZdZdd„ZRS(sVA connector for IPv6 SCTP sockets The SCTP implements a IPv4 TCP connection c Csoyttttƒ|_Wn ‚nXtdj o8tdj o+y|iittgƒWqk‚qkXndS(sinitialize a SCTP6ConnectorN( R@R^RMR\RïRDRRKRÐ(RR((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRú sN(RRRRR(((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRnô scCs]ddkl}d}||ƒ}x4tdƒD]&}|t||ƒd|d>7}q/W|S(s)convert an ascii IPv4 address into a Longiÿÿÿÿ(t inet_atoniiii(R@RoRhR!(tstringRoRRGRj((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyRV s  $cCsGd}x6tdƒD](}t|d@ƒd|}|dL}qW|d S(s)convert a long IPv4 address into a stringRiiÿt.iiÿÿÿÿ(Rhtstr(tlRRj((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pyt inet_ltoa s  cCsKt|tƒot|tƒpt‚d}d}d}t|ƒ}xÔ||joÆt||ƒ}|djo|d7}qHx7t|d|ƒD]"}t||ƒdjoPq”q”W|d|d>@djo>t|ƒdjo|d7}n|||d|d!7}n|}qHWt|ƒdjod|}|d7}n|S(s$Return a formatted list of flag names. flags - the flag values to format fmt - a sequence of bit numbers and descriptions as a string Compatible with bprintf() from BSD's route(8) command sources. This can be used to emulate %b from BSD's kernel printf(9).Rii it,t(RKRQRrR:R R!Rh(R5tfmtR=RjRétfmtlenR×((s6/usr/local/lib/python2.6/site-packages/pcs/__init__.pytbsprintf s.'      (6Rt __revision__R-R@tpcs.pcapRîR™R R t ExceptionRRMRRDRERIRJRTRWR\R]R_R^RqRwRxRtreserved_namesRƒRRÄRÅRÆRÇRÈRÉRÊRËRÌRìRR%R?RHRLROR[R]RlRmRnRVRtRz(((s6/usr/local/lib/python2.6/site-pa­Þ~initial threadšª¶JíÚ‡ ­Þ~initial threadšª¶JøÚ‡à˘­Þ~initial threadšª¶JÛ‡ckages/pcs/__init__.pyt:sd      ´ ; _Il Á $ ÿªô ÛÏ-½3L: ­Þ~initial threadšª¶JÛ‡ ­Þ~initial threadšª¶JÛ‡àË­Þ~initial threadšª¶J'Û‡­Þ~initial threadšª¶J1Û‡­Þ~initial threadšª¶Jw݇­Þ~initial threadšª¶J݇­Þ~initial threadšª¶J¨Ý‡¼°ÿÿÿ ´ÿÿÿ*­Þ~initial threadšª¶J´Ý‡/usr/local/lib/python2.6/site-packages/pcs}­Þ~initial threadšª¶JÐ݇stat[ò‡íAètª¶Jtª¶Jtª¶Jtª¶J­Þ~initial threadšª¶JÛ݇¼­Þ~initial threadšª¶Jé݇¼œ Ýдÿÿÿ*­Þ~initial threadšª¶Jõ݇/usr/local/lib/python2.6/site-packages/pcs}­Þ~initial threadšª¶JÞ‡stat[ò‡íAètª¶Jtª¶Jtª¶Jtª¶J­Þ~initial threadšª¶J)Þ‡¼­Þ~initial threadšª¶J5Þ‡¼°Àÿÿÿпÿÿÿ1­Þ~initial threadšª¶JAÞ‡/usr/local/lib/python2.6/site-packages/pcs/struct­Þ~initial threadšª¶JYÞ‡¼ ­Þ~initial threadšª¶JeÞ‡°Àÿÿÿ¶4­Þ~initial threadšª¶JqÞ‡/usr/local/lib/python2.6/site-packages/pcs/struct.so­Þ~initial threadšª¶J‹Þ‡ ­Þ~initial threadšª¶J–Þ‡°Àÿÿÿ¶:­Þ~initial threadšª¶J¢Þ‡/usr/local/lib/python2.6/site-packages/pcs/structmodule.so­Þ~initial threadšª¶J»Þ‡ ­Þ~initial threadšª¶JÆÞ‡°Àÿÿÿ¶4­Þ~initial threadšª¶JÒÞ‡/usr/local/lib/python2.6/site-packages/pcs/struct.py­Þ~initial threadšª¶JìÞ‡ ­Þ~initial threadšª¶J÷Þ‡°Àÿÿÿ¶5­Þ~initial threadšª¶J߇/usr/local/lib/python2.6/site-packages/pcs/struct.pyc­Þ~initial threadšª¶J߇­Þ~initial threadšª¶J,߇¼°Àÿÿÿпÿÿÿ7­Þ~initial threadšª¶J7߇/usr/home/gnn/Personal/Code/Networking/PCS/tests/struct­Þ~initial threadšª¶J\߇¼ ­Þ~initial threadšª¶Jh߇°Àÿÿÿ¶:­Þ~initial threadšª¶Jt߇/usr/home/gnn/Personal/Code/Networking/PCS/tests/struct.so­Þ~initial threadšª¶J߇ ­Þ~initial threadšª¶J›ß‡°Àÿÿÿ¶@­Þ~initial threadšª¶J§ß‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/structmodule.so­Þ~initial threadšª¶JÃ߇ ­Þ~initial threadšª¶JÎ߇°Àÿÿÿ¶:­Þ~initial threadšª¶JÚ߇/usr/home/gnn/Personal/Code/Networking/PCS/tests/struct.py­Þ~initial threadšª¶Jö߇ ­Þ~initial threadšª¶Jà‡°Àÿÿÿ¶;­Þ~initial threadšª¶J à‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/struct.pyc­Þ~initial threadšª¶J)à‡­Þ~initial threadšª¶J6à‡¼°Àÿÿÿпÿÿÿ­Þ~initial threadšª¶JBà‡/usr/local/lib/python2.6/struct­Þ~initial threadšª¶JWà‡¼ ­Þ~initial threadšª¶Jbà‡°Àÿÿÿ¶"­Þ~initial threadšª¶Jnà‡/usr/local/lib/python2.6/struct.so­Þ~initial threadšª¶J„à‡ ­Þ~initial threadšª¶Jà‡°Àÿÿÿ¶(­Þ~initial threadšª¶Jšà‡/usr/local/lib/python2.6/structmodule.so­Þ~initial threadšª¶J±à‡ ­Þ~initial threadšª¶J¼à‡°Àÿÿÿ¶"­Þ~initial threadšª¶JÇà‡/usr/local/lib/python2.6/struct.py­Þ~initial threadšª¶Jßà‡­Þ~initial threadšª¶Jêà‡½À¿ÿÿÿ}­Þ~initial threadšª¶Jöà‡stat[œ%$͸ô²JÖ²JÖ²J6Ö²J­Þ~initial threadšª¶Jᇽ ­Þ~initial threadšª¶J ᇰ»ÿÿÿ¶#­Þ~initial threadšª¶Já‡/usr/local/lib/python2.6/struct.pyc­Þ~initial threadšª¶J.ᇭÞ~initial threadšª¶J9ᇽ ºÿÿÿ}­Þ~initial threadšª¶JEá‡stat[K-¤ßAª¶Já²Já²JËá²J­Þ~initial threadšª¶JOᇽ ­Þ~initial threadšª¶J[á‡àËÓ­Þ~initial threadšª¶Jiá‡Ñò Ö²Jc@sddkTddklZdS(iÿÿÿÿ(t*(t _clearcacheN(t_structR(((s"/usr/local/lib/python2.6/struct.pyts ­Þ~initial threadšª¶Jsá‡Ë­Þ~initial threadšª¶J~ᇽ@{ÿÿÿ}­Þ~initial threadšª¶J‰á‡stat[K-¤ßAšª¶Já²Já²JËá²J­Þ~initial threadšª¶J”ᇽ ­Þ~initial threadšª¶Jžá‡àË­Þ~initial threadšª¶Jªá‡­Þ~initial threadšª¶J´á‡­Þ~initial threadšª¶JÃᇭÞ~initial threadšª¶JÕᇭÞ~initial threadšª¶JéᇼЭÿÿÿð¬ÿÿÿ8­Þ~initial threadšª¶Jõá‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_struct­Þ~initial threadšª¶J⇼ ­Þ~initial threadšª¶Jâ‡Эÿÿÿ¶;­Þ~initial threadšª¶J'â‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_struct.so­Þ~initial threadšª¶JC⇠­Þ~initial threadšª¶JNâ‡Эÿÿÿ¶A­Þ~initial threadšª¶JZâ‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_structmodule.so­Þ~initial threadšª¶Jv⇠­Þ~initial threadšª¶Jâ‡Эÿÿÿ¶;­Þ~initial threadšª¶Jâ‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_struct.py­Þ~initial threadšª¶J¨â‡ ­Þ~initial threadšª¶J´â‡Эÿÿÿ¶<­Þ~initial threadšª¶J¿â‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_struct.pyc­Þ~initial threadšª¶JÛ⇭Þ~initial threadšª¶Jè⇼Эÿÿÿð¬ÿÿÿ ­Þ~initial threadšª¶Jôâ‡/usr/local/lib/python2.6/_struct­Þ~initial threadšª¶J ㇼ ­Þ~initial threadšª¶Jã‡Эÿÿÿ¶#­Þ~initial threadšª¶J ã‡/usr/local/lib/python2.6/_struct.so­Þ~initial threadšª¶J6㇠­Þ~initial threadšª¶JAã‡Эÿÿÿ¶)­Þ~initial threadšª¶JMã‡/usr/local/lib/python2.6/_structmodule.so­Þ~initial threadšª¶Jc㇠­Þ~initial threadšª¶Jnã‡Эÿÿÿ¶#­Þ~initial threadšª¶Jzã‡/usr/local/lib/python2.6/_struct.py­Þ~initial threadšª¶J㇠­Þ~initial threadšª¶J›ã‡Эÿÿÿ¶$­Þ~initial threadšª¶J§ã‡/usr/local/lib/python2.6/_struct.pyc­Þ~initial threadšª¶J¼ã‡­Þ~initial threadšª¶J¼ã‡¼Эÿÿÿð¬ÿÿÿ.­Þ~initial threadšª¶JÝã‡/usr/local/lib/python2.6/plat-freebsd8/_struct­Þ~initial threadšª¶Jôㇼ ­Þ~initial threadšª¶Jþã‡Эÿÿÿ¶1­Þ~initial threadšª¶J ä‡/usr/local/lib/python2.6/plat-freebsd8/_struct.so­Þ~initial threadšª¶J!ä‡ ­Þ~initial threadšª¶J,ä‡Эÿÿÿ¶7­Þ~initial threadšª¶J7ä‡/usr/local/lib/python2.6/plat-freebsd8/_structmodule.so­Þ~initial threadšª¶JNä‡ ­Þ~initial threadšª¶JYä‡Эÿÿÿ¶1­Þ~initial threadšª¶Jdä‡/usr/local/lib/python2.6/plat-freebsd8/_struct.py­Þ~initial threadšª¶J{ä‡ ­Þ~initial threadšª¶J†ä‡Эÿÿÿ¶2­Þ~initial threadšª¶J’ä‡/usr/local/lib/python2.6/plat-freebsd8/_struct.pyc­Þ~initial threadšª¶J©ä‡­Þ~initial threadšª¶J´ä‡¼Эÿÿÿð¬ÿÿÿ'­Þ~initial threadšª¶J¿ä‡/usr/local/lib/python2.6/lib-tk/_struct­Þ~initial threadšª¶JÕ䇼 ­Þ~initial threadšª¶Jàä‡Эÿÿÿ¶*­Þ~initial threadšª¶Jëä‡/usr/local/lib/python2.6/lib-tk/_struct.so­Þ~initial threadšª¶Jå‡ ­Þ~initial threadšª¶J å‡Эÿÿÿ¶0­Þ~initial threadšª¶Jå‡/usr/local/lib/python2.6/lib-tk/_structmodule.so­Þ~initial threadšª¶J/å‡ ­Þ~initial threadšª¶J:å‡Эÿÿÿ¶*­Þ~initial threadšª¶JEå‡/usr/local/lib/python2.6/lib-tk/_struct.py­Þ~initial threadšª¶J\å‡ ­Þ~initial threadšª¶Jgå‡Эÿÿÿ¶+­Þ~initial threadšª¶Jrå‡/usr/local/lib/python2.6/lib-tk/_struct.pyc­Þ~initial threadšª¶JŠå‡­Þ~initial threadšª¶J¡å‡¼Эÿÿÿð¬ÿÿÿ(­Þ~initial threadšª¶J«å‡/usr/local/lib/python2.6/lib-old/_struct­Þ~initial threadšª¶JÁ凼 ­Þ~initial threadšª¶JÌå‡Эÿÿÿ¶+­Þ~initial threadšª¶J×å‡/usr/local/lib/python2.6/lib-old/_struct.so­Þ~initial threadšª¶Jîå‡ ­Þ~initial threadšª¶Jùå‡Эÿÿÿ¶1­Þ~initial threadšª¶Jæ‡/usr/local/lib/python2.6/lib-old/_structmodule.so­Þ~initial threadšª¶Jæ‡ ­Þ~initial threadšª¶J&æ‡Эÿÿÿ¶+­Þ~initial threadšª¶J2æ‡/usr/local/lib/python2.6/lib-old/_struct.py­Þ~initial threadšª¶JHæ‡ ­Þ~initial threadšª¶JSæ‡Эÿÿÿ¶,­Þ~initial threadšª¶J_æ‡/usr/local/lib/python2.6/lib-old/_struct.pyc­Þ~initial threadšª¶Ju懭Þ~initial threadšª¶J€æ‡¼Эÿÿÿð¬ÿÿÿ,­Þ~initial threadšª¶J‹æ‡/usr/local/lib/python2.6/lib-dynload/_struct­Þ~initial threadšª¶J¡æ‡¼ ­Þ~initial threadšª¶J¬æ‡Эÿÿÿ¶/­Þ~initial threadšª¶J·æ‡/usr/local/lib/python2.6/lib-dynload/_struct.so­Þ~initial threadšª¶JÏæ‡­Þ~initial threadšª¶JÜæ‡½À¬ÿÿÿ}­Þ~initial threadšª¶Jèæ‡stat[VÎíXíª¶J©²Jë²J»¯X©²J­Þ~initial threadšª¶Jò懽 ­Þ~initial threadšª¶Jüæ‡Tà sªÿÿÿ­Þ~initial threadšª¶Jç‡T ­Þ~initial threadšª¶Jç‡ÀBc0/­Þ~initial threadšª¶Jç‡/usr/local/lib/python2.6/lib-dynload/_struct.so­Þ~initial threadšª¶J4燭Þ~initial threadšª¶J>燽€©ÿÿÿ}­Þ~initial threadšª¶JIç‡stat[VÎíXíª¶J©²Jë²J»¯X©²J­Þ~initial threadšª¶Jƒç‡½ ­Þ~initial threadšª¶JŽç‡à¡s­Þ~initial threadšª¶Jžç‡ELF >à,@‡@8@ ^ ^```Ð%ø%¸¸¸Påtd^^^akiZO/BJA!Hj^K$SRa=V;h+ (U:`g4[%19\P&GbT-NW*f]5eY#X@d_c),'2>780FMQ6C<E3?"ILD. X`ڰа"°( Ä( à, ÈW ØW ^`°w¸HƒXƒhƒpƒÐ…^m  /‰4ñÿ¸ÈO÷,"1ãÎu´…–k.Š °(ß B_&²µ5Õ§¸mzq¦Tëyöz«;I%_ñÿÐ…3–dö}& ÈW»£6£á÷ËUð~HAÃÚ¯mXñÿÐ…­J ñÿpƒkñÿø….vÃÒŸ’Z; ã_DYNAMIC_GLOBAL_OFFSET_TABLE__init_fini__cxa_finalize_Jv_RegisterClasses_Py_NoneStructPyInt_FromLonginit_structPyString_FromStringPy_InitModule4_64PyType_TypePyType_ReadyPyModule_AddObjectPyModule_AddIntConstantPyErr_NewExceptionPyLong_FromStringPyInt_FromSsize_tPyTuple_NewPyString_FromStringAndSize_PyArg_ParseTupleAndKeywords_SizeTPyErr_FormatPyTuple_Pack_PyArg_ParseTuple_SizeTPyErr_SetS­Þ~initial threadšª¶J©ç‡8­Þ~initial threadšª¶J³ç‡Ýÿÿÿÿ­Þ~initial threadšª¶JÀç‡ÝP8­Þ~initial threadšª¶JÊç‡ÝP`­Þ~initial threadšª¶JÌç‡ÝP8­Þ~initial threadšª¶JÍç‡Ý°0`­Þ~initial threadšª¶JÎç‡Ý°­Þ~initial threadšª¶J]臭Þ~initial threadšª¶Jkè‡8­Þ~initial threadšª¶J|è‡Ý°ÿÿÿÿ­Þ~initial threadšª¶J‰è‡Ýc­Þ~initial threadšª¶JÓè‡Ic°­Þ~initial threadšª¶J“é‡I ­Þ~initial threadšª¶Jºé‡Tð s­Þ~initial threadšª¶JÅé‡T ­Þ~initial threadšª¶JÔé‡Tà sЩÿÿÿ­Þ~initial threadšª¶Jßé‡T ­Þ~initial threadšª¶Jêé‡Tð s­Þ~initial threadšª¶Jôé‡T­Þ~initial threadšª¶J;ꇭÞ~initial threadšª¶JIꇭÞ~initial threadšª¶JdꇭÞ~initial threadšª¶JrꇭÞ~initial threadšª¶J‚ꇼ°Àÿÿÿпÿÿÿ1­Þ~initial threadšª¶JŽê‡/usr/local/lib/python2.6/site-packages/pcs/socket­Þ~initial threadšª¶J¨ê‡¼ ­Þ~initial threadšª¶J³ê‡°Àÿÿÿ¶4­Þ~initial threadšª¶J¿ê‡/usr/local/lib/python2.6/site-packages/pcs/socket.so­Þ~initial threadšª¶JÙê‡ ­Þ~initial threadšª¶JäꇰÀÿÿÿ¶:­Þ~initial threadšª¶Jðê‡/usr/local/lib/python2.6/site-packages/pcs/socketmodule.so­Þ~initial threadšª¶J ë‡ ­Þ~initial threadšª¶J뇰Àÿÿÿ¶4­Þ~initial threadšª¶J ë‡/usr/local/lib/python2.6/site-packages/pcs/socket.py­Þ~initial threadšª¶J9ë‡ ­Þ~initial threadšª¶JD뇰Àÿÿÿ¶5­Þ~initial threadšª¶JPë‡/usr/local/lib/python2.6/site-packages/pcs/socket.pyc­Þ~initial threadšª¶Ji뇭Þ~initial threadšª¶Jy뇼°Àÿÿÿпÿÿÿ7­Þ~initial threadšª¶J„ë‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/socket­Þ~initial threadšª¶J ë‡¼ ­Þ~initial threadšª¶J«ë‡°Àÿÿÿ¶:­Þ~initial threadšª¶J·ë‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/socket.so­Þ~initial threadšª¶JÒë‡ ­Þ~initial threadšª¶JÞ뇰Àÿÿÿ¶@­Þ~initial threadšª¶Jêë‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/socketmodule.so­Þ~initial threadšª¶Jì‡ ­Þ~initial threadšª¶J쇰Àÿÿÿ¶:­Þ~initial threadšª¶Jì‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/socket.py­Þ~initial threadšª¶J8ì‡ ­Þ~initial threadšª¶JC쇰Àÿÿÿ¶;­Þ~initial threadšª¶JOì‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/socket.pyc­Þ~initial threadšª¶Jk쇭Þ~initial threadšª¶Jx쇼°Àÿÿÿпÿÿÿ­Þ~initial threadšª¶Jƒì‡/usr/local/lib/python2.6/socket­Þ~initial threadšª¶J™ì‡¼ ­Þ~initial threadšª¶J¤ì‡°Àÿÿÿ¶"­Þ~initial threadšª¶J¯ì‡/usr/local/lib/python2.6/socket.so­Þ~initial threadšª¶JÆì‡ ­Þ~initial threadšª¶JÑ쇰Àÿÿÿ¶(­Þ~initial threadšª¶JÜì‡/usr/local/lib/python2.6/socketmodule.so­Þ~initial threadšª¶Jóì‡ ­Þ~initial threadšª¶Jþ쇰Àÿÿÿ¶"­Þ~initial threadšª¶J í‡/usr/local/lib/python2.6/socket.py­Þ~initial threadšª¶J"퇭Þ~initial threadšª¶J-퇽À¿ÿÿÿ}­Þ~initial threadšª¶J9í‡stat[‘%$p!ô²JÖ²JÖ²JKF$Ö²J­Þ~initial threadšª¶JC퇽 ­Þ~initial threadšª¶JN퇰»ÿÿÿ¶#­Þ~initial threadšª¶JYí‡/usr/local/lib/python2.6/socket.pyc­Þ~initial threadšª¶Jp퇭Þ~initial threadšª¶Jp퇽 ºÿÿÿ}­Þ~initial threadšª¶Jpí‡stat[8-¤Eª¶Já²Já²Jç: á²J­Þ~initial threadšª¶J¥í‡½ ­Þ~initial threadšª¶J°í‡àË­Þ~initial threadšª¶JÀí‡Ñò Ö²Jc!@s*dZddkZddkTyddkZWnej onsXeed„ZddklZddklZl Z l Z l Z l Z l Z lZlZlZlZlZlZddkZddkZddkZyddklZWn#ej oddklZnXyddklZWnej o d ZnXd d gZeieieƒƒeZei i!ƒi"d ƒo­hZ#d e#djoe&d?fZ&nd@dAdBdCdDdEfZ(dFe)fdG„ƒYZ*dHe)fdI„ƒYZ+e+ZZ,dJe)fdK„ƒYZ-e)ƒZ.e.dL„Z/dS(MsÜThis module provides socket operations and some related functions. On Unix, it supports IP (Internet Protocol) and Unix domain sockets. On other systems, it only supports IP. Functions specific for a socket are available as methods of the socket object. Functions: socket() -- create a new socket object socketpair() -- create a pair of new socket objects [*] fromfd() -- create a socket object from an open file descriptor [*] gethostname() -- return the current hostname gethostbyname() -- map a hostname to its IP number gethostbyaddr() -- map an IP number or hostname to DNS info getservbyname() -- map a service name and a protocol name to a port number getprotobyname() -- mape a protocol name (e.g. 'tcp') to a number ntohs(), ntohl() -- convert 16, 32 bit int from network to host byte order htons(), htonl() -- convert 16, 32 bit int from host to network byte order inet_aton() -- convert IP addr string (123.45.67.89) to 32-bit packed format inet_ntoa() -- convert 32-bit packed format IP to string (123.45.67.89) ssl() -- secure socket layer support (only available if configured) socket.getdefaulttimeout() -- get the default timeout value socket.setdefaulttimeout() -- set the default timeout value create_connection() -- connects to an address, with an optional timeout [*] not available on all platforms! Special objects: SocketType -- type object for socket objects error -- exception raised for I/O errors has_ipv6 -- boolean value indicating if IPv6 is supported Integer constants: AF_INET, AF_UNIX -- socket domains (first argument to socket() call) SOCK_STREAM, SOCK_DGRAM, SOCK_RAW -- socket types (second argument) Many other constants may be defined; these may be used in calls to the setsockopt() and getsockopt() methods. iÿÿÿÿN(t*cCs5ddk}tidtddƒ|i|||ƒS(Niÿÿÿÿs;socket.ssl() is deprecated. Use ssl.wrap_socket() instead.t stackleveli(tssltwarningstwarntDeprecationWarningtsslwrap_simple(tsocktkeyfiletcertfilet_realssl((s"/usr/local/lib/python2.6/socket.pyR7s   (tSSLError( tRAND_addtRAND_egdt RAND_statustSSL_ERROR_ZERO_RETURNtSSL_ERROR_WANT_READtSSL_ERROR_WANT_WRITEtSSL_ERROR_WANT_X509_LOOKUPtSSL_ERROR_SYSCALLt SSL_ERROR_SSLtSSL_ERROR_WANT_CONNECTt SSL_ERROR_EOFtSSL_ERROR_INVALID_ERROR_CODE(tStringIO(tEBADFi tgetfqdntcreate_connectiontwinsThe operation was interrupted.i'sA bad file handle was passed.i'sPermission denied.i's!A fault occurred on the network??i's#An invalid operation was attempted.i&'s The socket operation would blocki3's,A blocking operation is already in progress.i4'sThe network address is in use.i@'sThe connection has been reset.iF'sThe network has been shut down.iJ'sThe operation timed out.iL'sConnection refused.iM'sThe name is too long.iO'sThe host is down.iP'sThe host is unreachable.iQ'terrorTabtcCsš|iƒ}| p |djo tƒ}nyt|ƒ\}}}Wntj on;X|id|ƒx&|D]}d|­Þ~initial threadšª¶JË퇭Þ~initial threadšª¶JÖ퇽@{ÿÿÿ}­Þ~initial threadšª¶Jáí‡stat[8-¤Ešª¶Já²Já²Jç: á²J­Þ~initial threadšª¶Jë퇽 ­Þ~initial threadšª¶Jõí‡àË­Þ~initial threadšª¶Jî‡joPqtqtW|}|S(sGet fully qualified domain name from name. An empty argument is interpreted as meaning the local host. First the hostname returned by gethostbyaddr() is checked, then possibly existing aliases. In case no FQDN is available, hostname from gethostname() is returned. s0.0.0.0it.(tstript gethostnamet gethostbyaddrterrortinsert(tnamethostnametaliasestipaddrs((s"/usr/local/lib/python2.6/socket.pyRws    tbindtconnectt connect_extfilenotlistent getpeernamet getsocknamet getsockoptt setsockopttsendallt setblockingt settimeoutt gettimeouttshutdowntnttioctltriscost sleeptaskwtrecvtrecvfromt recv_intot recvfrom_intotsendtsendtot _closedsocketcBs7eZgZd„ZeZZZZZZ eZ RS(cGsttdƒ‚dS(NsBad file descriptor(R#R(targs((s"/usr/local/lib/python2.6/socket.pyt_dummy¤s( t__name__t __module__t __slots__RCR?R;R=R@R<R>t __getattr__(((s"/usr/local/lib/python2.6/socket.pyRA¢s t _socketobjectcBsøeZeiZddgeeƒZeeddd„Z d„Z ei ie _d„Z ei ie _d„Z ddd „Zed „d d ƒZed „d dƒZed„d dƒZdZx&eD]ZeeeeefdUqÎW[[RS(t_sockt __weakref__icCsZ|djot|||ƒ}n||_x'tD]}t||t||ƒƒq3WdS(N(tNonet _realsocketRIt_delegate_methodstsetattrtgetattr(tselftfamilyttypetprotoRItmethod((s"/usr/local/lib/python2.6/socket.pyt__init__´s   cCs=tƒ|_|ii}xtD]}t|||ƒqWdS(N(RARIRCRMRN(RPtdummyRT((s"/usr/local/lib/python2.6/socket.pytclose»s   cCs(|iiƒ\}}td|ƒ|fS(NRI(RItacceptRH(RPRtaddr((s"/usr/local/lib/python2.6/socket.pyRXÂscCstd|iƒS(sadup() -> socket object Return a new socket object connected to the same system resource.RI(RHRI(RP((s"/usr/local/lib/python2.6/socket.pytdupÇstriÿÿÿÿcCst|i||ƒS(s¾makefile([mode[, bufsize]]) -> file object Return a regular file object corresponding to the socket. The mode and bufsize arguments are as for the built-in open() function.(t _fileobjectRI(RPtmodetbufsize((s"/usr/local/lib/python2.6/socket.pytmakefileÍscCs |iiS((RIRQ(RP((s"/usr/local/lib/python2.6/socket.pytÔstdocsthe socket familycCs |iiS((RIRR(RP((s"/usr/local/lib/python2.6/socket.pyR`Õssthe socket typecCs |iiS((RIRS(RP((s"/usr/local/lib/python2.6/socket.pyR`Össthe socket protocolsVdef %s(self, *args): return self._sock.%s(*args) %s.__doc__ = _realsocket.%s.__doc__ N(RDRERLt__doc__tlistRMRFtAF_INETt SOCK_STREAMRKRURWRXRZR_tpropertyRQRRRSt_st_socketmethodst_m(((s"/usr/local/lib/python2.6/socket.pyRH®s"    R\c BsÝeZdZdZdZddddddd d d g Zd d ed„Zd„Ze eddƒZ d„Z d„Z d„Z d„Zd„Zd„Zd„Zd d„Zd d„Zdd„Zd„Zd„ZRS(s-Fa­Þ~initial threadšª¶JFî‡ ­Þ~initial threadšª¶JQî‡àË­Þ~initial threadšª¶Jaî‡ux file object attached to a socket object.i sR]R^t softspaceRIt _rbufsizet _wbufsizet_rbuft_wbuft_closetrbiÿÿÿÿcCs©||_||_|djo |i}n||_t|_|djo d|_n'|djo|i|_n ||_||_tƒ|_ g|_ ||_ dS(Nii( RIR]tdefault_bufsizeR^tFalseRjRkRlRRmRnRo(RPRR]R^RW((s"/usr/local/lib/python2.6/socket.pyRUës             cCs |idjS(N(RIRK(RP((s"/usr/local/lib/python2.6/socket.pyt _getclosedsRasTrue if the file is closedcCsHz|io|iƒnWd|io|iiƒnd|_XdS(N(RItflushRoRWRK(RP((s"/usr/local/lib/python2.6/socket.pyRWs   cCsy|iƒWnnXdS(N(RW(RP((s"/usr/local/lib/python2.6/socket.pyt__del__scCs=|io/di|iƒ}g|_|ii|ƒndS(NR(RntjoinRIR2(RPtbuffer((s"/usr/local/lib/python2.6/socket.pyRts  cCs |iiƒS(N(RIR,(RP((s"/usr/local/lib/python2.6/socket.pyR,scCs}t|ƒ}|pdS|ii|ƒ|idjp3|idjo d|jp|iƒ|ijo|iƒndS(Niis (tstrRntappendRlt _get_wbuf_lenRt(RPtdata((s"/usr/local/lib/python2.6/socket.pytwrite!s cCsZ|iitdtt|ƒƒƒ|idjp|iƒ|ijo|iƒndS(Ni( RntextendtfilterRKtmapRxRlRzRt(RPRc((s"/usr/local/lib/python2.6/socket.pyt writelines+s"cCs.d}x!|iD]}|t|ƒ7}qW|S(Ni(Rntlen(RPtbuf_lentx((s"/usr/local/lib/python2.6/socket.pyRz3s  c Cs¼t|i|iƒ}|i}|iddƒ|djoQtƒ|_x7to/|ii|ƒ}|pPn|i |ƒqJW|i ƒS|i ƒ}||joC|idƒ|i |ƒ}tƒ|_|ii |i ƒƒ|Stƒ|_x·to¯||}|ii|ƒ}|pPnt |ƒ}||jo | o|S||jo|i |ƒ~Pn||jptd||f‚|i |ƒ||7}~q÷W|i ƒSdS(Niisrecv(%d) returned %d bytes(tmaxRkRqRmtseekRtTrueRIR;R|tgetvaluettelltreadRtAssertionError( RPtsizetrbufsizetbufR{R‚trvtlefttn((s"/usr/local/lib/python2.6/socket.pyR‰9sL             !  c CsŒ|i}|iddƒ|iƒdjom|idƒ|i|ƒ}|idƒpt|ƒ|jo'tƒ|_|ii|iƒƒ|S~n|djoI|i djo‚|idƒ|iƒg}tƒ|_d}|i i }x7|djo)|dƒ}|pPn|i |ƒqóWdi|ƒS|iddƒtƒ|_xto…|i i |i ƒ}|pPn|idƒ}|djo7|d7}|i|| ƒ|ii||ƒ~Pn|i|ƒqWW|iƒS|iddƒ|iƒ}||joC|idƒ|i|ƒ} tƒ|_|ii|iƒƒ| Stƒ|_xto |i i |i ƒ}|pPn||} |idd| ƒ}|djoG|d7}|ii||ƒ|o|i|| ƒPq|| Snt|ƒ} | |jo | o|S| | jo*|i|| ƒ|ii|| ƒPn|i|ƒ|| 7}qjW|iƒSdS(Niis iR(­Þ~initial threadšª¶Jlî‡ ­Þ~initial threadšª¶Jvî‡àËï ­Þ~initial threadšª¶J…î‡RmR…RˆtreadlinetendswithRRR|R‰RkRKRIR;RyRvR†tfindR‡( RPR‹RtblinetbuffersR{R;tnlR‚RŽRR((s"/usr/local/lib/python2.6/socket.pyR‘us’  #                       icCsmd}g}xZtoR|iƒ}|pPn|i|ƒ|t|ƒ7}|o||joPqqW|S(Ni(R†R‘RyR(RPtsizehintttotalRctline((s"/usr/local/lib/python2.6/socket.pyt readlinesËs   cCs|S(N((RP((s"/usr/local/lib/python2.6/socket.pyt__iter__ÚscCs!|iƒ}|p t‚n|S(N(R‘t StopIteration(RPR™((s"/usr/local/lib/python2.6/socket.pytnextÝs  (RDRERbRqR%RFRrRURsRftclosedRWRuRtR,R|R€RzR‰R‘RšR›R(((s"/usr/local/lib/python2.6/socket.pyR\às*         < V  c CsÒd}|\}}x°t||dtƒD]™}|\}}}} } d} yEt|||ƒ} |tj o| i|ƒn| i| ƒ| SWq(tj o$}| dj o| iƒqÁq(Xq(Wt|‚dS(s›Connect to *address* and return the socket object. Convenience function. Connect to *address* (a 2-tuple ``(host, port)``) and return the socket object. Passing the optional *timeout* parameter will set the timeout on the socket instance before attempting to connect. If no *timeout* is supplied, the global default timeout setting returned by :func:`getdefaulttimeout` is used. s!getaddrinfo returns an empty listiN( t getaddrinfoReRKtsockett_GLOBAL_DEFAULT_TIMEOUTR4R*R#RW( taddressttimeouttmsgthosttporttrestaftsocktypeRSt canonnametsaR((s"/usr/local/lib/python2.6/socket.pyRås     (0Rbt_sockett_sslt ImportErrorRKRR tsslerrorR R RRRRRRRRRRtostsysRt cStringIORterrnoRt__all__R}t_get_exports_listR RLtplatformtlowert startswithRRyRRhR%RMtobjectRARHt SocketTypeR\R¡R(((s"/usr/local/lib/python2.6/socket.pyt,sr   R$                      0 ÿ ­Þ~initial threadšª¶Jî‡ç ­Þ~initial threadšª¶Jšî‡àË­Þ~initial threadšª¶J¥î‡­Þ~initial threadšª¶J¯î‡­Þ~initial threadšª¶J Þ~initial threadšª¶J3Þ~initial threadšª¶JFЭÿÿÿð¬ÿÿÿ8­Þ~initial threadšª¶JRï‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_socket­Þ~initial threadšª¶Jm ­Þ~initial threadšª¶Jxï‡Эÿÿÿ¶;­Þ~initial threadšª¶Jƒï‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_socket.so­Þ~initial threadšª¶JŸï‡ ­Þ~initial threadšª¶Jªï‡Эÿÿÿ¶A­Þ~initial threadšª¶Jµï‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_socketmodule.so­Þ~initial threadšª¶JÑï‡ ­Þ~initial threadšª¶JÛï‡Эÿÿÿ¶;­Þ~initial threadšª¶Jçï‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_socket.py­Þ~initial threadšª¶Jð‡ ­Þ~initial threadšª¶J ð‡Эÿÿÿ¶<­Þ~initial threadšª¶Jð‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_socket.pyc­Þ~initial threadšª¶J4ð‡­Þ~initial threadšª¶JAð‡¼Эÿÿÿð¬ÿÿÿ ­Þ~initial threadšª¶JLð‡/usr/local/lib/python2.6/_socket­Þ~initial threadšª¶Jað‡¼ ­Þ~initial threadšª¶Jkð‡Эÿÿÿ¶#­Þ~initial threadšª¶Jvð‡/usr/local/lib/python2.6/_socket.so­Þ~initial threadšª¶JŒð‡ ­Þ~initial threadšª¶J—ð‡Эÿÿÿ¶)­Þ~initial threadšª¶J¢ð‡/usr/local/lib/python2.6/_socketmodule.so­Þ~initial threadšª¶J·ð‡ ­Þ~initial threadšª¶JÂð‡Эÿÿÿ¶#­Þ~initial threadšª¶JÍð‡/usr/local/lib/python2.6/_socket.py­Þ~initial threadšª¶Jãð‡ ­Þ~initial threadšª¶Jíð‡Эÿÿÿ¶$­Þ~initial threadšª¶Jùð‡/usr/local/lib/python2.6/_socket.pyc­Þ~initial threadšª¶Jñ‡­Þ~initial threadšª¶Jñ‡¼Эÿÿÿð¬ÿÿÿ.­Þ~initial threadšª¶J#ñ‡/usr/local/lib/python2.6/plat-freebsd8/_socket­Þ~initial threadšª¶J:ñ‡¼ ­Þ~initial threadšª¶JDñ‡Эÿÿÿ¶1­Þ~initial threadšª¶JOñ‡/usr/local/lib/python2.6/plat-freebsd8/_socket.so­Þ~initial threadšª¶Jgñ‡ ­Þ~initial threadšª¶Jqñ‡Эÿÿÿ¶7­Þ~initial threadšª¶J|ñ‡/usr/local/lib/python2.6/plat-freebsd8/_socketmodule.so­Þ~initial threadšª¶J’ñ‡ ­Þ~initial threadšª¶J’ñ‡Эÿÿÿ¶1­Þ~initial threadšª¶J“ñ‡/usr/local/lib/python2.6/plat-freebsd8/_socket.py­Þ~initial threadšª¶J“ñ‡ ­Þ~initial threadšª¶J“ñ‡Эÿÿÿ¶2­Þ~initial threadšª¶J“ñ‡/usr/local/lib/python2.6/plat-freebsd8/_socket.pyc­Þ~initial threadšª¶J“ñ‡­Þ~initial threadšª¶J“ñ‡¼Эÿÿÿð¬ÿÿÿ'­Þ~initial threadšª¶J“ñ‡/usr/local/lib/python2.6/lib-tk/_socket­Þ~initial threadšª¶J“ñ‡¼ ­Þ~initial threadšª¶J“ñ‡Эÿÿÿ¶*­Þ~initial threadšª¶J“ñ‡/usr/local/lib/python2.6/lib-tk/_socket.so­Þ~initial threadšª¶J“ñ‡ ­Þ~initial threadšª¶J“ñ‡Эÿÿÿ¶0­Þ~initial threadšª¶J“ñ‡/usr/local/lib/python2.6/lib-tk/_socketmodule.so­Þ~initial threadšª¶J“ñ‡ ­Þ~initial threadšª¶J“ñ‡Эÿÿÿ¶*­Þ~initial threadšª¶J“ñ‡/usr/local/lib/python2.6/lib-tk/_socket.py­Þ~initial threadšª¶J“ñ‡ ­Þ~initial threadšª¶J“ñ‡Эÿÿÿ¶+­Þ~initial threadšª¶J“ñ‡/usr/local/lib/python2.6/lib-tk/_socket.pyc­Þ~initial threadšª¶J“ñ‡­Þ~initial threadšª¶J"ó‡¼Эÿÿÿð¬ÿÿÿ(­Þ~initial threadšª¶J.ó‡/usr/local/lib/python2.6/lib-old/_socket­Þ~initial threadšª¶JFó‡¼ ­Þ~initial threadšª¶JQó‡Эÿÿÿ¶+­Þ~initial threadšª¶J]ó‡/usr/local/lib/python2.6/lib-old/_socket.so­Þ~initial threadšª¶Jtó‡ ­Þ~initial threadšª¶J€ó‡Эÿÿÿ¶1­Þ~initial threadšª¶JŒó‡/usr/local/lib/python2.6/lib-old/_socketmodule.so­Þ~initial threadšª¶J£ó‡ ­Þ~initial threadšª¶J®ó‡Эÿÿÿ¶+­Þ~initial threadšª¶Jºó‡/usr/local/lib/python2.6/lib-old/_socket.py­Þ~initial threadšª¶JÒó‡ ­Þ~initial threadšª¶JÝó‡Эÿÿÿ¶,­Þ~initial threadšª¶Jéó‡/usr/local/lib/python2.6/lib-old/_socket.pyc­Þ~initial threadšª¶Jô‡­Þ~initial threadšª¶J ô‡¼Эÿÿÿð¬ÿÿÿ,­Þ~initial threadšª¶Jô‡/usr/local/lib/python2.6/lib-dynload/_socket­Þ~initial threadšª¶J-ô‡¼ ­Þ~initial threadšª¶J8ô‡Эÿÿÿ¶/­Þ~initial threadšª¶JDô‡/usr/local/lib/python2.6/lib-dynload/_socket.so­Þ~initial threadšª¶J]ô‡­Þ~initial threadšª¶Jjô‡½À¬ÿÿÿ}­Þ~initial threadšª¶Jvô‡stat[{Îí8ñª¶Jº²Jë²J|Œº²J­Þ~initial threadšª¶Jô‡½ ­Þ~initial threadšª¶J‹ô‡Tà sªÿÿÿ­Þ~initial threadšª¶J–ô‡T ­Þ~initial threadšª¶J ô‡Cc0/­Þ~initial threadšª¶J¬ô‡/usr/local/lib/python2.6/lib-dynload/_socket.so­Þ~initial threadšª¶JÄô‡­Þ~initial threadšª¶JÏô‡½€©ÿÿÿ}­Þ~initial threadšª¶JÛô‡stat[{Îí8ñª¶Jº²Jë²J|Œº²J­Þ~initial threadšª¶Jåô‡½ ­Þ~initial threadšª¶Jïô‡à¡s­Þ~initial threadšª¶Jÿô‡ELF >7@ ß@8@„–„–   `>>€Ù€Ù€ÙPåtd|–|–|–ƒƒSNErDyGF8€xpJf_lucTAmb{U>1v*?Cw=i[.}zQ]oXnj!`(qah-:34e^O|RI~$s‚kg%)/2+"<BL@ PK#Y;,5&\MHd0'W697tZV @ˆhp°H)p1 „1 7 øƒ „ |– ÈЀÙÛ Û0Û8Û`Þy­­c›ñÿ€ÙÑdï@ƒ×,"1a;½ßs'êFSJs20O= e p1‡>_Õ#\ §Tš®¢ÜH§OC÷T“ž ãcÛ²Î=ë1yÅóÏLõ àK82K4½wùÆñÿ`ÞCþ‰¹Ñw[•& øƒëÊ Òo…agl9./w'–¿ñÿ`ÞeJ ñÿ8Ûù­Þ~initial threadšª¶J õ‡8­Þ~initial threadšª¶Jõ‡Ýàÿÿÿÿ­Þ~initial threadšª¶J"õ‡Ýà8­Þ~initial threadšª¶J,õ‡Ýà ­Þ~initial threadšª¶JQõ‡Ýà8­Þ~initial threadšª¶J\õ‡Ý€!@ ­Þ~initial threadšª¶Jyõ‡Ý€!­Þ~initial threadšª¶J©õ‡­Þ~initial threadšª¶J¶õ‡8­Þ~initial threadšª¶JÇõ‡Ý0ÿÿÿÿ­Þ~initial threadšª¶JÓõ‡Ýc­Þ~initial threadšª¶Jö‡Ic0­Þ~initial threadšª¶JUö‡I ­Þ~initial threadšª¶J™ö‡Tð s­Þ~initial threadšª¶J¤ö‡T ­Þ~initial threadšª¶J²ö‡Tà sЩÿÿÿ­Þ~initial threadšª¶J¼ö‡T ­Þ~initial threadšª¶JÆö‡Tð s­Þ~initial threadšª¶JÑö‡T­Þ~initial threadšª¶Jº÷‡­Þ~initial threadšª¶JÈ÷‡­Þ~initial threadšª¶Jø‡¼Эÿÿÿð¬ÿÿÿ5­Þ~initial threadšª¶Jø‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_ssl­Þ~initial threadšª¶J/ø‡¼ ­Þ~initial threadšª¶J;ø‡Эÿÿÿ¶8­Þ~initial threadšª¶JFø‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_ssl.so­Þ~initial threadšª¶Jcø‡ ­Þ~initial threadšª¶Jnø‡Эÿÿÿ¶>­Þ~initial threadšª¶Jzø‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_sslmodule.so­Þ~initial threadšª¶J–ø‡ ­Þ~initial threadšª¶J¡ø‡Эÿÿÿ¶8­Þ~initial threadšª¶J­ø‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_ssl.py­Þ~initial threadšª¶JÉø‡ ­Þ~initial threadšª¶JÔø‡Эÿÿÿ¶9­Þ~initial threadšª¶Jßø‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/_ssl.pyc­Þ~initial threadšª¶Jûø‡­Þ~initial threadšª¶J ù‡¼Эÿÿÿð¬ÿÿÿ­Þ~initial threadšª¶Jù‡/usr/local/lib/python2.6/_ssl­Þ~initial threadšª¶J*ù‡¼ ­Þ~initial threadšª¶J5ù‡Эÿÿÿ¶ ­Þ~initial threadšª¶JAù‡/usr/local/lib/python2.6/_ssl.so­Þ~initial threadšª¶JWù‡ ­Þ~initial threadšª¶Jbù‡Эÿÿÿ¶&­Þ~initial threadšª¶Jnù‡/usr/local/lib/python2.6/_sslmodule.so­Þ~initial threadšª¶Jƒù‡ ­Þ~initial threadšª¶Jù‡Эÿÿÿ¶ ­Þ~initial threadšª¶Jšù‡/usr/local/lib/python2.6/_ssl.py­Þ~initial threadšª¶J°ù‡ ­Þ~initial threadšª¶J»ù‡Эÿÿÿ¶!­Þ~initial threadšª¶JÇù‡/usr/local/lib/python2.6/_ssl.pyc­Þ~initial threadšª¶JÝù‡­Þ~initial threadšª¶Jèù‡¼Эÿÿÿð¬ÿÿÿ+­Þ~initial threadšª¶Jóù‡/usr/local/lib/python2.6/plat-freebsd8/_ssl­Þ~initial threadšª¶J ú‡¼ ­Þ~initial threadšª¶Jú‡Эÿÿÿ¶.­Þ~initial threadšª¶J ú‡/usr/local/lib/python2.6/plat-freebsd8/_ssl.so­Þ~initial threadšª¶J8ú‡ ­Þ~initial threadšª¶JCú‡Эÿÿÿ¶4­Þ~initial threadšª¶JOú‡/usr/local/lib/python2.6/plat-freebsd8/_sslmodule.so­Þ~initial threadšª¶Jgú‡ ­Þ~initial threadšª¶Jrú‡Эÿÿÿ¶.­Þ~initial threadšª¶J}ú‡/usr/local/lib/python2.6/plat-freebsd8/_ssl.py­Þ~initial threadšª¶J•ú‡ ­Þ~initial threadšª¶J ú‡Эÿÿÿ¶/­Þ~initial threadšª¶J¬ú‡/usr/local/lib/python2.6/plat-freebsd8/_ssl.pyc­Þ~initial threadšª¶JÄú‡­Þ~initial threadšª¶JÏú‡¼Эÿÿÿð¬ÿÿÿ$­Þ~initial threadšª¶JÙú‡/usr/local/lib/python2.6/lib-tk/_ssl­Þ~initial threadšª¶Jðú‡¼ ­Þ~initial threadšª¶Jûú‡Эÿÿÿ¶'­Þ~initial threadšª¶Jû‡/usr/local/lib/python2.6/lib-tk/_ssl.so­Þ~initial threadšª¶Jû‡ ­Þ~initial threadšª¶J*û‡Эÿÿÿ¶-­Þ~initial threadšª¶J5û‡/usr/local/lib/python2.6/lib-tk/_sslmodule.so­Þ~initial threadšª¶JLû‡ ­Þ~initial threadšª¶JXû‡Эÿÿÿ¶'­Þ~initial threadšª¶J‹û‡/usr/local/lib/python2.6/lib-tk/_ssl.py­Þ~initial threadšª¶J£û‡ ­Þ~initial threadšª¶J¯û‡Эÿÿÿ¶(­Þ~initial threadšª¶J»û‡/usr/local/lib/python2.6/lib-tk/_ssl.pyc­Þ~initial threadšª¶JÒû‡­Þ~initial threadšª¶JÝû‡¼Эÿÿÿð¬ÿÿÿ%­Þ~initial threadšª¶Jèû‡/usr/local/lib/python2.6/lib-old/_ssl­Þ~initial threadšª¶Jÿû‡¼ ­Þ~initial threadšª¶J ü‡Эÿÿÿ¶(­Þ~initial threadšª¶Jü‡/usr/local/lib/python2.6/lib-old/_ssl.so­Þ~initial threadšª¶J-ü‡ ­Þ~initial threadšª¶J8ü‡Эÿÿÿ¶.­Þ~initial threadšª¶JDü‡/usr/local/lib/python2.6/lib-old/_sslmodule.so­Þ~initial threadšª¶J[ü‡ ­Þ~initial threadšª¶Jgü‡Эÿÿÿ¶(­Þ~initial threadšª¶J|ü‡/usr/local/lib/python2.6/lib-old/_ssl.py­Þ~initial threadšª¶J”ü‡ ­Þ~initial threadšª¶J ü‡Эÿÿÿ¶)­Þ~initial threadšª¶J¬ü‡/usr/local/lib/python2.6/lib-old/_ssl.pyc­Þ~initial threadšª¶JÃü‡­Þ~initial threadšª¶JÏü‡¼Эÿÿÿð¬ÿÿÿ)­Þ~initial threadšª¶JÚü‡/usr/local/lib/python2.6/lib-dynload/_ssl­Þ~initial threadšª¶Jñü‡¼ ­Þ~initial threadšª¶Jüü‡Эÿÿÿ¶,­Þ~initial threadšª¶Jý‡/usr/local/lib/python2.6/lib-dynload/_ssl.so­Þ~initial threadšª¶J!ý‡­Þ~initial threadšª¶J.ý‡½À¬ÿÿÿ}­Þ~initial threadšª¶J:ý‡stat[|Îí`ñª¶Jº²Jë²J¡Tº²J­Þ~initial threadšª¶JDý‡½ ­Þ~initial threadšª¶JNý‡Tà sªÿÿÿ­Þ~initial threadšª¶JYý‡T ­Þ~initial threadšª¶Jdý‡@Cc-,­Þ~initial threadšª¶JŸý‡/usr/local/lib/python2.6/lib-dynload/_ssl.so­Þ~initial threadšª¶J¸ý‡­Þ~initial threadšª¶JÃý‡½€©ÿÿÿ}­Þ~initial threadšª¶JÎý‡stat[|Îí`ñª¶Jº²Jë²J¡Tº²J­Þ~initial threadšª¶JÙý‡½ ­Þ~initial threadšª¶Jãý‡à¡s­Þ~initial threadšª¶Jýý‡ELF >À4@Ày@8@ŒdŒd d d dà¸r¸r¸r°°Påtd„d„d„dƒ™wOsR=L…\WŽY@‰‚JxB“gzeŒ|[&Iˆ"h~o;X€DFrU}—A{‘:•k2–”di„mM/C 9a†t’p,GEq'‹b.c`3‡˜uj%(15!*-)8N$ZPQ?]THS6<v^+0nVf#7>y_K4ƒlŠ ˜ðBx¸ "0- D- À4 ø[ \ „d d@o¸rhtxtˆtt€x(-"U(‰B&©cWd Ä X<Jñÿ¸r f ´í}«_wIº£&"1GíÀWÑuÍNÔE¬VŠ vNߢ jêš oÀ0-ÜÕ‘ÇI¦Ãn" î9G)ò5-lf&+#}TI(®1| ·Xº$Y"d’”É *ÞX8ñÿ€x‡ñA9\™õ­Þ~initial threadšª¶J þ‡8­Þ~initial threadšª¶Jþ‡Ý€ÿÿÿÿ­Þ~initial threadšª¶Jþ‡ÝÀ!8­Þ~initial threadšª¶J*þ‡ÝÀ!p­Þ~initial threadšª¶JIþ‡ÝÀ!8­Þ~initial threadšª¶JTþ‡Ý 2 `­Þ~initial threadšª¶Jiþ‡Ý 2­Þ~initial threadšª¶J“þ‡­Þ~initial threadšª¶J þ‡­Þ~initial threadšª¶J®þ‡!Pc­Þ~initial threadšª¶J¼þ‡/lib/libssl.so.6­Þ~initial threadšª¶JÎþ‡!­Þ~initial threadšª¶JÙþ‡!Pc­Þ~initial threadšª¶Jæþ‡/usr/lib/libssl.so.6­Þ~initial threadšª¶Jûþ‡! ­Þ~initial threadšª¶Jÿ‡ 'c²s­Þ~initial threadšª¶Jÿ‡/usr/lib/libssl.so.6­Þ~initial threadšª¶J%ÿ‡­Þ~initial threadšª¶J0ÿ‡½`©ÿÿÿ}­Þ~initial threadšª¶J<ÿ‡stat[L% $P-ª¶J2µJ2µJ ñ 2µJ­Þ~initial threadšª¶JFÿ‡½ ­Þ~initial threadšª¶JQÿ‡à¡s­Þ~initial threadšª¶Jiÿ‡ELF >àS@ ë@8@€@€@€@€@€@P£¤ Ñ Ñ Ñ  Påtdx@x@x@ ýÞœCÕ™à%†¨Ë€ZyáLÞС7±ÑQüÀQ1Û–ðšzåŸ.É–r®ŠÆ‹> Iµª(:# E¢÷>r—4ù'äyYú̘òøÓ]/O"6åT¥ÝøÆŒ=+»¦ÚôðÏ ßçFèÀ©ÄÝ~RVdc©rØ-Ï’b½38 lWƒìDuãÍwÜ,C¡ xz -Y1#&¸‘[í·W²^â”÷A§z^­îë¯\ítmž)s€i+ª:‰ȶèù×NõÙ¯äÐ5S#›u±Ã×ÎTeØæÓûúÃgÏçG'õÒŠÚoÛ?ºÑ®Ðcý8È‚ê­ÄaÜá_ßû-ú§m —³wÜp UÖ‘ƒu\<„û¿¡e~{µj¿€÷C™ˆAUÕñKˆݸ¦ÇªèTÖéê)FG¹…½ü?;b“B¼!öÉ1[ØOî¹ÅšÌf.ó“ºyÓ`áºã§xM ïR¼|ŽÂ¬©ÅÎâ¨]SAÍM"¬ëËÁï@<íXJô‰'$"02oLpt]?I‚Š•Kž8ab)JS5=¦m*²³ÅUq–i^G7°Ž(eãBd£%”HZõDOöEæjnÇM†ÑÙ´¾¢+*&%ÛŒó9 Fð ¸Pì4YÉšW‰XÇÌ{|(k6chk¤þµVég„5±ÍåÀZ«­Þ~initial threadšª¶Jtÿ‡8­Þ~initial threadšª¶Jÿ‡Ýðÿÿÿÿ­Þ~initial threadšª¶J‹ÿ‡Ý@28­Þ~initial threadšª¶J•ÿ‡Ý@2P­Þ~initial threadšª¶Jäÿ‡Ý@28­Þ~initial threadšª¶Jïÿ‡Ý€F°@­Þ~initial threadšª¶J ‡Ý€F­Þ~initial threadšª¶J@‡­Þ~initial threadšª¶JN‡­Þ~initial threadšª¶JY‡!Pc­Þ~initial threadšª¶Jf‡/lib/libcrypto.so.6­Þ~initial threadšª¶Jx‡! ­Þ~initial threadšª¶Jƒ‡€'c²s­Þ~initial threadšª¶Jއ/lib/libcrypto.so.6­Þ~initial threadšª¶JŸ‡­Þ~initial threadšª¶Jª‡½`©ÿÿÿ}­Þ~initial threadšª¶J¶‡statY·$@’ª¶JµJµJ ´ µJ­Þ~initial threadšª¶JÀ‡½ ­Þ~initial threadšª¶Jʇà¡s­Þ~initial threadšª¶JÛ‡ELF >0S@ ®@8@d%d%€%€%%€%%;èe(()()Påtd\%\%\%µ t Ë M žv µ «º¿ 8 Ù »(µ þ ÆJNÜ  h iœ – ®u¤ ±  ‡ À ´ K ¿ ã ø ÷· ‡: ¾* ¦+î< Ñ++ - T ª ™ #[ ¹ &»¨ î  ¦   £ 1 À\ „ ž_ 9 @³ ¬ ä ¥õ Š/ _ ây î £ Ö 3n}¦T£ 0 l© b Ð ™ B Ñ™D qœ ðÛ ½ ¤ N ( Š ò« Œ … _9 ©g — z# i Ò Å %N • ‰ f ¿ ²T E Q ‰ÖØ ¬‡ ’ tlåZ ïƒ B z ÅÚ¿ î ½t n( ³ x  g…$ X þQi è waŒì~ ó— õ € Ö!‘ Ž T Ê & ãG Η@ ²Ét© a x ß k x¢ Ó ÊÍ Þ ‘  _ †k Yÿ Å» Dk X å D Þ 7dë¸ Ù ìS ’ : Tú ˜ d †Ó ç +a 3©ØÕ¾ “ pBI #åD{ Ó P = t” 4% © M ˆ £ ; 0 UË ï ÞÛ”2 š 7 L ˆ²G F 5Ue &  … ? ¾˜ à ô^YçáQ ® ° rå  ¨ > ö–à n TT §P hmØ Â ‹  X`:0 ,À §~ ˆ- eõ ‡ Ï X +ú R õÖù°ͳG  ’jM öÎ  š ·Wö ¡  s l Åì CB ï €å> D‹ v ŒÄ " s ¬c à   t 3Uœ•5ì Âã’‘¸Hþ x I… b¢ ñ 2 @ €^ , B‘2ö ± c  eÁž  ¹ ßì  ¨D u \dó º 1 Û˜#!c‹ · f8 ýd H l ñ û 4 Å ~ Ä *< » õ$ T › µ í ± ^Ì“{ — )lô ¶ ¼ %I ¼â   5a p qL <-# " À aÚ ` uÔ‚þ¶  Ë ³^ à é ' m & U ¢Ü¨ : ´ ®´ ® 5 B I ã ¦  Q  6±Ô &ŠŸ# œ € á U¦ ЯR ìjð ŠW ½ › @ è § o  WzO= j š ä v | ù«  / ½ 7d å ð:ç Ü: Ú ºR zèRÒ ç ÷S _ž ±y t 1 ­ A § û™{ N ó Å Ør žo —4• j ç µ 3× d Sqc. ˜ˆ’1h O = ˆ 4« A þ ¯  –}  v y ï 5 Øÿñ % ú é 5I à ¯ rEÁ Ÿ Ô ; p \V pl .§‚¥ 7 ZTm ) U k `zq S ô÷ sv g`¯n ž é­Þ~initial threadšª¶J$‡8­Þ~initial threadšª¶J/‡Ý)ÿÿÿÿ­Þ~initial threadšª¶J<‡Ý0G8­Þ~initial threadšª¶JG‡Ý0G0­Þ~initial threadšª¶JX‡Ý0G8­Þ~initial threadšª¶Jc‡ÝPlP ­Þ~initial threadšª¶J‰‡ÝPl ­Þ~initial threadšª¶Jµ‡J p ­Þ~initial threadšª¶J‡J­Þ~initial threadšª¶J‡­Þ~initial threadšª¶J‡8­Þ~initial threadšª¶J&‡Ý ÿÿÿÿ­Þ~initial threadšª¶J3‡Ýc­Þ~initial threadšª¶JLJIc ­Þ~initial threadšª¶J‡I8­Þ~initial threadšª¶J؇ÝÐ/ÿÿÿÿ­Þ~initial threadšª¶Jå‡Ýc­Þ~initial threadšª¶JÕ‡IcÐ/­Þ~initial threadšª¶J&‡I8­Þ~initial threadšª¶Jè‡ÝPÛÿÿÿÿ­Þ~initial threadšª¶Jõ‡Ýc­Þ~initial threadšª¶J ‡IcPÛ­Þ~initial threadšª¶J} ‡I ­Þ~initial threadšª¶J³‡Tð s­Þ~initial threadšª¶JÀ‡T ­Þ~initial threadšª¶Jê‡Tà sЩÿÿÿ­Þ~initial threadšª¶Jõ‡T ­Þ~initial threadšª¶J‡Tð s­Þ~initial threadšª¶J ‡T ­Þ~initial threadšª¶J‡Tà sЩÿÿÿ­Þ~initial threadšª¶J&‡T ­Þ~initial threadšª¶J0‡Tð s­Þ~initial threadšª¶J:‡T ­Þ~initial threadšª¶JJ‡Tà sЩÿÿÿ­Þ~initial threadšª¶JT‡T ­Þ~initial threadšª¶J_‡Tð s­Þ~initial threadšª¶Ji‡T­Þ~initial threadšª¶J#‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J0‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JJ‡¼­Þ~initial threadšª¶JU‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J`‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jt‡¼­Þ~initial threadšª¶J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JЇ/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J£‡¼­Þ~initial threadšª¶J®‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¹‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J·¼­Þ~initial threadšª¶J܇¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jç‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jý‡¼­Þ~initial threadšª¶J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/share/nls/libc/C­Þ~initial threadšª¶J&‡¼­Þ~initial threadšª¶J1‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J<‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J]‡¼­Þ~initial threadšª¶Ji‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jt‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jˆ‡¼­Þ~initial threadšª¶J ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J«‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÁ‡¼­Þ~initial threadšª¶J̇¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jׇ/usr/share/nls/libc/C­Þ~initial threadšª¶Jꇼ­Þ~initial threadšª¶Jõ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J!‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J,‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JA‡¼­Þ~initial threadšª¶JN‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JY‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jn‡¼­Þ~initial threadšª¶Jy‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J„‡/usr/share/nls/libc/C­Þ~initial threadšª¶J—‡¼­Þ~initial threadšª¶J¢‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J­‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jć¼­Þ~initial threadšª¶Jχ¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÙ‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J­Þ~initial threadšª¶Jû‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J'‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J1‡/usr/share/nls/libc/C­Þ~initial threadšª¶JD‡¼­Þ~initial threadšª¶JP‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JZ‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jq‡¼­Þ~initial threadšª¶J{‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J†‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J›‡¼­Þ~initial threadšª¶J¨‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J³‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jɇ¼­Þ~initial threadšª¶JÓ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÞ‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jò‡¼­Þ~initial threadšª¶Jý‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J?‡¼­Þ~initial threadšª¶JM‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JX‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jn‡¼­Þ~initial threadšª¶J|‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jˆ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J¨‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J³‡/usr/share/nls/libc/C­Þ~initial threadšª¶JƇ¼­Þ~initial threadšª¶Jч¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J܇/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jò‡¼­Þ~initial threadšª¶Jý‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J*‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J5‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JJ‡¼­Þ~initial threadšª¶JU‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J`‡/usr/share/nls/libc/C­Þ~initial threadšª¶Js‡¼­Þ~initial threadšª¶J~‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‰‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JŸ‡¼­Þ~initial threadšª¶J¹‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JƇ/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÛ‡¼­Þ~initial threadšª¶J釼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jô‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J ‡¼­Þ~initial threadšª¶J!‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J,‡/usr/share/nls/libc/C­Þ~initial threadšª¶J?‡¼­Þ~initial threadšª¶JJ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JU‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jk‡¼­Þ~initial threadšª¶Jw‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J–‡¼­Þ~initial threadšª¶J¤‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¯‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jć¼­Þ~initial threadšª¶Jχ¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÙ‡/usr/share/nls/libc/C­Þ~initial threadšª¶J퇼­Þ~initial threadšª¶Jø‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J$‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J/‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JD‡¼­Þ~initial threadšª¶JQ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J\‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jq‡¼­Þ~initial threadšª¶J|‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡‡/usr/share/nls/libc/C­Þ~initial threadšª¶J›‡¼­Þ~initial threadšª¶J¥‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J°‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JLJ¼­Þ~initial threadšª¶JÒ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J݇/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jñ‡¼­Þ~initial threadšª¶Jÿ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J*‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J5‡/usr/share/nls/libc/C­Þ~initial threadšª¶JH‡¼­Þ~initial threadšª¶JS‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J^‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jt‡¼­Þ~initial threadšª¶J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‰‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jž‡¼­Þ~initial threadšª¶J¬‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J·‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J̇¼­Þ~initial threadšª¶Jׇ¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Já‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jõ‡¼­Þ~initial threadšª¶J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J ‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J!‡¼­Þ~initial threadšª¶J,‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J7‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JK‡¼­Þ~initial threadšª¶JY‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jd‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jy‡¼­Þ~initial threadšª¶J„‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¢‡¼­Þ~initial threadšª¶J­‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¸‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J·¼­Þ~initial threadšª¶JÙ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jä‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J*‡¼­Þ~initial threadšª¶J9‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JD‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JY‡¼­Þ~initial threadšª¶Jd‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jo‡/usr/share/nls/libc/C­Þ~initial threadšª¶J‚‡¼­Þ~initial threadšª¶J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J˜‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J®‡¼­Þ~initial threadšª¶Jº‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jć/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÙ‡¼­Þ~initial threadšª¶J懼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jñ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/share/nls/libc/C­Þ~initial threadšª¶J/‡¼­Þ~initial threadšª¶J:‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JD‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JD‡¼­Þ~initial threadšª¶Jq‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J|‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J‘‡¼­Þ~initial threadšª¶Jž‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J©‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¿‡¼­Þ~initial threadšª¶Jɇ¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÔ‡/usr/share/nls/libc/C­Þ~initial threadšª¶J臼­Þ~initial threadšª¶Jò‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jý‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J‡¼­Þ~initial threadšª¶J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J)‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J>‡¼­Þ~initial threadšª¶JK‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JV‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jk‡¼­Þ~initial threadšª¶Jv‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡/usr/share/nls/libc/C­Þ~initial threadšª¶J”‡¼­Þ~initial threadšª¶JŸ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jª‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÀ‡¼­Þ~initial threadšª¶Jˇ¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÖ‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jꇼ­Þ~initial threadšª¶Jø‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J% ‡¼­Þ~initial threadšª¶J0 ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J; ‡/usr/share/nls/libc/C­Þ~initial threadšª¶JO ‡¼­Þ~initial threadšª¶JZ ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jd ‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J{ ‡¼­Þ~initial threadšª¶J’ ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¦ ‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¼ ‡¼­Þ~initial threadšª¶JÉ ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÔ ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jê ‡¼­Þ~initial threadšª¶Jõ ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jÿ ‡/usr/share/nls/libc/C­Þ~initial threadšª¶J!‡¼­Þ~initial threadšª¶J!‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J(!‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J?!‡¼­Þ~initial threadšª¶JJ!‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JU!‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jj!‡¼­Þ~initial threadšª¶Jw!‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‚!‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J˜!‡¼­Þ~initial threadšª¶J£!‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J­!‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÁ!‡¼­Þ~initial threadšª¶J"‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J "‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J$"‡¼­Þ~initial threadšª¶J/"‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J:"‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JO"‡¼­Þ~initial threadšª¶J]"‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡"‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jž"‡¼­Þ~initial threadšª¶J½"‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÈ"‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÜ"‡¼­Þ~initial threadšª¶Jç"‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jò"‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J#‡¼­Þ~initial threadšª¶J#‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J#‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J3#‡¼­Þ~initial threadšª¶JA#‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JL#‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Ja#‡¼­Þ~initial threadšª¶Jl#‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jw#‡/usr/share/nls/libc/C­Þ~initial threadšª¶J‹#‡¼­Þ~initial threadšª¶J–#‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¡#‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J·#‡¼­Þ~initial threadšª¶JÂ#‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÍ#‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jâ#‡¼­Þ~initial threadšª¶Jï#‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jû#‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J$‡¼­Þ~initial threadšª¶J$‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J&$‡/usr/share/nls/libc/C­Þ~initial threadšª¶J9$‡¼­Þ~initial threadšª¶JD$‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JO$‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jf$‡¼­Þ~initial threadšª¶Jq$‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J|$‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J‘$‡¼­Þ~initial threadšª¶Jž$‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J©$‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¾$‡¼­Þ~initial threadšª¶JÉ$‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÔ$‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jè$‡¼­Þ~initial threadšª¶Jó$‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jþ$‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J%‡¼­Þ~initial threadšª¶J0%‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J<%‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JQ%‡¼­Þ~initial threadšª¶J_%‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jj%‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J%‡¼­Þ~initial threadšª¶JŠ%‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J•%‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¨%‡¼­Þ~initial threadšª¶J¼%‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÇ%‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÞ%‡¼­Þ~initial threadšª¶Jé%‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jô%‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J &‡¼­Þ~initial threadšª¶J&‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J!&‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J6&‡¼­Þ~initial threadšª¶JA&‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JL&‡/usr/share/nls/libc/C­Þ~initial threadšª¶J_&‡¼­Þ~initial threadšª¶Jj&‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Ju&‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J‹&‡¼­Þ~initial threadšª¶J–&‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¡&‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jµ&‡¼­Þ~initial threadšª¶JÂ&‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÎ&‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jã&‡¼­Þ~initial threadšª¶Jî&‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jø&‡/usr/share/nls/libc/C­Þ~initial threadšª¶J '‡¼­Þ~initial threadšª¶J'‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J!'‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J8'‡¼­Þ~initial threadšª¶JC'‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JM'‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jb'‡¼­Þ~initial threadšª¶Jo'‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J{'‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J'‡¼­Þ~initial threadšª¶J›'‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¥'‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¹'‡¼­Þ~initial threadšª¶JÃ'‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÎ'‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jå'‡¼­Þ~initial threadšª¶Jð'‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jú'‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J(‡¼­Þ~initial threadšª¶J(‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J1(‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JG(‡¼­Þ~initial threadšª¶JR(‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J](‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jp(‡¼­Þ~initial threadšª¶J{(‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J…(‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jœ(‡¼­Þ~initial threadšª¶JÊ(‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÖ(‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jí(‡¼­Þ~initial threadšª¶Jü(‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J)‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J)‡¼­Þ~initial threadšª¶J')‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J2)‡/usr/share/nls/libc/C­Þ~initial threadšª¶JF)‡¼­Þ~initial threadšª¶JP)‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J[)‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jr)‡¼­Þ~initial threadšª¶J})‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡)‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jœ)‡¼­Þ~initial threadšª¶Jª)‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jµ)‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÊ)‡¼­Þ~initial threadšª¶JÕ)‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jß)‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jó)‡¼­Þ~initial threadšª¶J7*‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JC*‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JZ*‡¼­Þ~initial threadšª¶Je*‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jp*‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J…*‡¼­Þ~initial threadšª¶J“*‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jž*‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J³*‡¼­Þ~initial threadšª¶J¾*‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÉ*‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÜ*‡¼­Þ~initial threadšª¶Jç*‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jò*‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J+‡¼­Þ~initial threadšª¶J+‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J+‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J3+‡¼­Þ~initial threadšª¶J@+‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JK+‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J`+‡¼­Þ~initial threadšª¶Jl+‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jv+‡/usr/share/nls/libc/C­Þ~initial threadšª¶JŠ+‡¼­Þ~initial threadšª¶J•+‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JŸ+‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¶+‡¼­Þ~initial threadšª¶JÁ+‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JË+‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J,‡¼­Þ~initial threadšª¶J,‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J,‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JA,‡¼­Þ~initial threadšª¶JM,‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JX,‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jl,‡¼­Þ~initial threadšª¶Jw,‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‚,‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J˜,‡¼­Þ~initial threadšª¶J¤,‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J®,‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÃ,‡¼­Þ~initial threadšª¶JÑ,‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÜ,‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jñ,‡¼­Þ~initial threadšª¶Jü,‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J-‡/usr/share/nls/libc/C­Þ~initial threadšª¶J-‡¼­Þ~initial threadšª¶J%-‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J0-‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JF-‡¼­Þ~initial threadšª¶JQ-‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J\-‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jq-‡¼­Þ~initial threadšª¶J~-‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‰-‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jž-‡¼­Þ~initial threadšª¶J©-‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J´-‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÇ-‡¼­Þ~initial threadšª¶JÒ-‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÝ-‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jó-‡¼­Þ~initial threadšª¶Jþ-‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J .‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J.‡¼­Þ~initial threadšª¶J+.‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J7.‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JK.‡¼­Þ~initial threadšª¶JV.‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Ja.‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jt.‡¼­Þ~initial threadšª¶J.‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JŠ.‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J .‡¼­Þ~initial threadšª¶J¬.‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¶.‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JË.‡¼­Þ~initial threadšª¶JØ.‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jã.‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jø.‡¼­Þ~initial threadšª¶J/‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J/‡/usr/share/nls/libc/C­Þ~initial threadšª¶J!/‡¼­Þ~initial threadšª¶J,/‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J7/‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JM/‡¼­Þ~initial threadšª¶JX/‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jc/‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jx/‡¼­Þ~initial threadšª¶J…/‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J/‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¥/‡¼­Þ~initial threadšª¶J°/‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J»/‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÎ/‡¼­Þ~initial threadšª¶JÙ/‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jä/‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jû/‡¼­Þ~initial threadšª¶J0‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J0‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J%0‡¼­Þ~initial threadšª¶J20‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J=0‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JR0‡¼­Þ~initial threadšª¶J]0‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jh0‡/usr/share/nls/libc/C­Þ~initial threadšª¶J{0‡¼­Þ~initial threadšª¶J†0‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‘0‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J§0‡¼­Þ~initial threadšª¶J²0‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J½0‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÒ0‡¼­Þ~initial threadšª¶Jß0‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jê0‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jÿ0‡¼­Þ~initial threadšª¶J 1‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J1‡/usr/share/nls/libc/C­Þ~initial threadšª¶J(1‡¼­Þ~initial threadšª¶J31‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J>1‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JT1‡¼­Þ~initial threadšª¶J_1‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jj1‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J1‡¼­Þ~initial threadšª¶JŒ1‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J—1‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¬1‡¼­Þ~initial threadšª¶J¸1‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂ1‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÔ1‡¼­Þ~initial threadšª¶Jê1‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jõ1‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J 2‡¼­Þ~initial threadšª¶J2‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J 2‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J42‡¼­Þ~initial threadšª¶JA2‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JL2‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J`2‡¼­Þ~initial threadšª¶Jk2‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Ju2‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jˆ2‡¼­Þ~initial threadšª¶J’2‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jœ2‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J²2‡¼­Þ~initial threadšª¶J½2‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÇ2‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÛ2‡¼­Þ~initial threadšª¶Jè2‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jó2‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J3‡¼­Þ~initial threadšª¶J3‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J3‡/usr/share/nls/libc/C­Þ~initial threadšª¶J.3‡¼­Þ~initial threadšª¶J93‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JC3‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JY3‡¼­Þ~initial threadšª¶Jd3‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jn3‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J‚3‡¼­Þ~initial threadšª¶J3‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J™3‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J®3‡¼­Þ~initial threadšª¶J¸3‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÃ3‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÖ3‡¼­Þ~initial threadšª¶Jà3‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jê3‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J4‡¼­Þ~initial threadšª¶J 4‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J4‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J)4‡¼­Þ~initial threadšª¶J64‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JA4‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JU4‡¼­Þ~initial threadšª¶J`4‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jj4‡/usr/share/nls/libc/C­Þ~initial threadšª¶J}4‡¼­Þ~initial threadšª¶J‡4‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‘4‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J§4‡¼­Þ~initial threadšª¶J±4‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¼4‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÐ4‡¼­Þ~initial threadšª¶JÝ4‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jç4‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jü4‡¼­Þ~initial threadšª¶J5‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J5‡/usr/share/nls/libc/C­Þ~initial threadšª¶J#5‡¼­Þ~initial threadšª¶J.5‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J85‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JN5‡¼­Þ~initial threadšª¶JY5‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jc5‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jw5‡¼­Þ~initial threadšª¶J5‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jš5‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¯5‡¼­Þ~initial threadšª¶J¹5‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÄ5‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÖ5‡¼­Þ~initial threadšª¶Já5‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jë5‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jí5‡¼­Þ~initial threadšª¶Jí5‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jî5‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jî5‡¼­Þ~initial threadšª¶J€6‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JŒ6‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¢6‡¼­Þ~initial threadšª¶J­6‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¸6‡/usr/share/nls/libc/C­Þ~initial threadšª¶JË6‡¼­Þ~initial threadšª¶J×6‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Já6‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jø6‡¼­Þ~initial threadšª¶J7‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J 7‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J"7‡¼­Þ~initial threadšª¶J/7‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J;7‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JP7‡¼­Þ~initial threadšª¶J[7‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Je7‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jy7‡¼­Þ~initial threadšª¶J„7‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JŽ7‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¥7‡¼­Þ~initial threadšª¶J°7‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J»7‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÐ7‡¼­Þ~initial threadšª¶JÝ7‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jè7‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jý7‡¼­Þ~initial threadšª¶J8‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J8‡/usr/share/nls/libc/C­Þ~initial threadšª¶J&8‡¼­Þ~initial threadšª¶J18‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J<8‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JR8‡¼­Þ~initial threadšª¶J]8‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jh8‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J|8‡¼­Þ~initial threadšª¶JŠ8‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J•8‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jª8‡¼­Þ~initial threadšª¶Jµ8‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÀ8‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÓ8‡¼­Þ~initial threadšª¶JÞ8‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jé8‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jÿ8‡¼­Þ~initial threadšª¶J 9‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J9‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J*9‡¼­Þ~initial threadšª¶J79‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JB9‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JW9‡¼­Þ~initial threadšª¶Jb9‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jm9‡/usr/share/nls/libc/C­Þ~initial threadšª¶J€9‡¼­Þ~initial threadšª¶J‹9‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J–9‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J­9‡¼­Þ~initial threadšª¶J¸9‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂ9‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J×9‡¼­Þ~initial threadšª¶Jä9‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jï9‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J:‡¼­Þ~initial threadšª¶J:‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J:‡/usr/share/nls/libc/C­Þ~initial threadšª¶J-:‡¼­Þ~initial threadšª¶J9:‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JC:‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JZ:‡¼­Þ~initial threadšª¶Je:‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jo:‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J„:‡¼­Þ~initial threadšª¶J‘:‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J:‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J²:‡¼­Þ~initial threadšª¶J½:‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÇ:‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÛ:‡¼­Þ~initial threadšª¶Jæ:‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jð:‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J;‡¼­Þ~initial threadšª¶J;‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J;‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J2;‡¼­Þ~initial threadšª¶J?;‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JJ;‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J_;‡¼­Þ~initial threadšª¶Jj;‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Ju;‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jˆ;‡¼­Þ~initial threadšª¶J’;‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J’;‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¾;‡¼­Þ~initial threadšª¶JÊ;‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÔ;‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jé;‡¼­Þ~initial threadšª¶J÷;‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J<‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J<‡¼­Þ~initial threadšª¶J"<‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J,<‡/usr/share/nls/libc/C­Þ~initial threadšª¶J@<‡¼­Þ~initial threadšª¶JK<‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JU<‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jl<‡¼­Þ~initial threadšª¶Jw<‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‚<‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J—<‡¼­Þ~initial threadšª¶J¤<‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¯<‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÄ<‡¼­Þ~initial threadšª¶JÏ<‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÚ<‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jí<‡¼­Þ~initial threadšª¶Jø<‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J=‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J=‡¼­Þ~initial threadšª¶J%=‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J/=‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JD=‡¼­Þ~initial threadšª¶JQ=‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J\=‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jq=‡¼­Þ~initial threadšª¶J|=‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‡=‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jš=‡¼­Þ~initial threadšª¶J¥=‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J°=‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÆ=‡¼­Þ~initial threadšª¶JÑ=‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÜ=‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jñ=‡¼­Þ~initial threadšª¶Jþ=‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J >‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J>‡¼­Þ~initial threadšª¶J)>‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J3>‡/usr/share/nls/libc/C­Þ~initial threadšª¶JG>‡¼­Þ~initial threadšª¶JR>‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J]>‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Js>‡¼­Þ~initial threadšª¶J~>‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J”>‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jª>‡¼­Þ~initial threadšª¶J·>‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂ>‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J×>‡¼­Þ~initial threadšª¶Jâ>‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jí>‡/usr/share/nls/libc/C­Þ~initial threadšª¶J?‡¼­Þ~initial threadšª¶J ?‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J?‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J,?‡¼­Þ~initial threadšª¶J8?‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JB?‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JW?‡¼­Þ~initial threadšª¶Jd?‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jo?‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J„?‡¼­Þ~initial threadšª¶J?‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jš?‡/usr/share/nls/libc/C­Þ~initial threadšª¶J­?‡¼­Þ~initial threadšª¶JÅ?‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÒ?‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jè?‡¼­Þ~initial threadšª¶Jô?‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jþ?‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J@‡¼­Þ~initial threadšª¶J!@‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J,@‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JA@‡¼­Þ~initial threadšª¶JL@‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JV@‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jj@‡¼­Þ~initial threadšª¶Ju@‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J€@‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J–@‡¼­Þ~initial threadšª¶J¡@‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¬@‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÀ@‡¼­Þ~initial threadšª¶JÍ@‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÙ@‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jî@‡¼­Þ~initial threadšª¶Jù@‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JA‡/usr/share/nls/libc/C­Þ~initial threadšª¶JA‡¼­Þ~initial threadšª¶J!A‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J,A‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JBA‡¼­Þ~initial threadšª¶JMA‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JXA‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JmA‡¼­Þ~initial threadšª¶JzA‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J…A‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JšA‡¼­Þ~initial threadšª¶J¥A‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J°A‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÃA‡¼­Þ~initial threadšª¶JÎA‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÙA‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JïA‡¼­Þ~initial threadšª¶JúA‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JB‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JB‡¼­Þ~initial threadšª¶J'B‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J2B‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JGB‡¼­Þ~initial threadšª¶JRB‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J\B‡/usr/share/nls/libc/C­Þ~initial threadšª¶JoB‡¼­Þ~initial threadšª¶JªB‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JµB‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÌB‡¼­Þ~initial threadšª¶J×B‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JâB‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J÷B‡¼­Þ~initial threadšª¶JC‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JC‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J%C‡¼­Þ~initial threadšª¶J0C‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J;C‡/usr/share/nls/libc/C­Þ~initial threadšª¶JNC‡¼­Þ~initial threadšª¶JYC‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JdC‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JzC‡¼­Þ~initial threadšª¶J…C‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JC‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¤C‡¼­Þ~initial threadšª¶J²C‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J½C‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÒC‡¼­Þ~initial threadšª¶JÝC‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JèC‡/usr/share/nls/libc/C­Þ~initial threadšª¶JûC‡¼­Þ~initial threadšª¶JD‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JD‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J'D‡¼­Þ~initial threadšª¶J2D‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J=D‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JQD‡¼­Þ~initial threadšª¶J^D‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JjD‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JD‡¼­Þ~initial threadšª¶J‰D‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J”D‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¨D‡¼­Þ~initial threadšª¶J³D‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¾D‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÔD‡¼­Þ~initial threadšª¶JßD‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JêD‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JþD‡¼­Þ~initial threadšª¶J E‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JE‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J,E‡¼­Þ~initial threadšª¶J6E‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JAE‡/usr/share/nls/libc/C­Þ~initial threadšª¶JSE‡¼­Þ~initial threadšª¶JSE‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JSE‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JŠE‡¼­Þ~initial threadšª¶J•E‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J E‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JµE‡¼­Þ~initial threadšª¶JÂE‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÖE‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JìE‡¼­Þ~initial threadšª¶J÷E‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JF‡/usr/share/nls/libc/C­Þ~initial threadšª¶JF‡¼­Þ~initial threadšª¶J F‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J*F‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JAF‡¼­Þ~initial threadšª¶JLF‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JVF‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JkF‡¼­Þ~initial threadšª¶JxF‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JƒF‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J˜F‡¼­Þ~initial threadšª¶J£F‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J®F‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÁF‡¼­Þ~initial threadšª¶JÌF‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J×F‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JíF‡¼­Þ~initial threadšª¶JøF‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JG‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JG‡¼­Þ~initial threadšª¶J%G‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J0G‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JEG‡¼­Þ~initial threadšª¶JPG‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J[G‡/usr/share/nls/libc/C­Þ~initial threadšª¶JnG‡¼­Þ~initial threadšª¶JyG‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JƒG‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JšG‡¼­Þ~initial threadšª¶J¥G‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¯G‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÄG‡¼­Þ~initial threadšª¶JÑG‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÜG‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JñG‡¼­Þ~initial threadšª¶JüG‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JH‡/usr/share/nls/libc/C­Þ~initial threadšª¶JH‡¼­Þ~initial threadšª¶J%H‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J0H‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JFH‡¼­Þ~initial threadšª¶JQH‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J\H‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JqH‡¼­Þ~initial threadšª¶J~H‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‰H‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JžH‡¼­Þ~initial threadšª¶J©H‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J´H‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÈH‡¼­Þ~initial threadšª¶JÓH‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÝH‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JôH‡¼­Þ~initial threadšª¶JþH‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J I‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JI‡¼­Þ~initial threadšª¶J+I‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J6I‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JKI‡¼­Þ~initial threadšª¶JVI‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JaI‡/usr/share/nls/libc/C­Þ~initial threadšª¶JtI‡¼­Þ~initial threadšª¶J¥I‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J±I‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÉI‡¼­Þ~initial threadšª¶JÔI‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JßI‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JôI‡¼­Þ~initial threadšª¶JJ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J J‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J"J‡¼­Þ~initial threadšª¶J-J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J8J‡/usr/share/nls/libc/C­Þ~initial threadšª¶JKJ‡¼­Þ~initial threadšª¶JVJ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JaJ‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JwJ‡¼­Þ~initial threadšª¶J‚J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JJ‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¢J‡¼­Þ~initial threadšª¶J¯J‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JºJ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÏJ‡¼­Þ~initial threadšª¶JÚJ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JåJ‡/usr/share/nls/libc/C­Þ~initial threadšª¶JøJ‡¼­Þ~initial threadšª¶JK‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J K‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J$K‡¼­Þ~initial threadšª¶J/K‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J9K‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JNK‡¼­Þ~initial threadšª¶J[K‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JfK‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J{K‡¼­Þ~initial threadšª¶J†K‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‘K‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¤K‡¼­Þ~initial threadšª¶J¯K‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JºK‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÐK‡¼­Þ~initial threadšª¶JÛK‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JæK‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JúK‡¼­Þ~initial threadšª¶JL‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JL‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J(L‡¼­Þ~initial threadšª¶J3L‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J=L‡/usr/share/nls/libc/C­Þ~initial threadšª¶JQL‡¼­Þ~initial threadšª¶J[L‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JfL‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J|L‡¼­Þ~initial threadšª¶J‡L‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J’L‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J§L‡¼­Þ~initial threadšª¶J´L‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¿L‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÔL‡¼­Þ~initial threadšª¶JßL‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JéL‡/usr/share/nls/libc/C­Þ~initial threadšª¶JýL‡¼­Þ~initial threadšª¶JM‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JM‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J(M‡¼­Þ~initial threadšª¶J3M‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J>M‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JSM‡¼­Þ~initial threadšª¶J`M‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JkM‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J€M‡¼­Þ~initial threadšª¶J‹M‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J•M‡/usr/share/nls/libc/C­Þ~initial threadšª¶J©M‡¼­Þ~initial threadšª¶J´M‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¾M‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÕM‡¼­Þ~initial threadšª¶JàM‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JêM‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÿM‡¼­Þ~initial threadšª¶J N‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JN‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J,N‡¼­Þ~initial threadšª¶J7N‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JBN‡/usr/share/nls/libc/C­Þ~initial threadšª¶JUN‡¼­Þ~initial threadšª¶J`N‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JkN‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JN‡¼­Þ~initial threadšª¶JŒN‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J–N‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J«N‡¼­Þ~initial threadšª¶JåN‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JðN‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JO‡¼­Þ~initial threadšª¶JO‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JO‡/usr/share/nls/libc/C­Þ~initial threadšª¶JO‡¼­Þ~initial threadšª¶JCO‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JOO‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JeO‡¼­Þ~initial threadšª¶JqO‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J{O‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JO‡¼­Þ~initial threadšª¶JžO‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J©O‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¾O‡¼­Þ~initial threadšª¶JÉO‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÔO‡/usr/share/nls/libc/C­Þ~initial threadšª¶JçO‡¼­Þ~initial threadšª¶JòO‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JüO‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JP‡¼­Þ~initial threadšª¶JP‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J(P‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J=P‡¼­Þ~initial threadšª¶JKP‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JUP‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JjP‡¼­Þ~initial threadšª¶JuP‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J€P‡/usr/share/nls/libc/C­Þ~initial threadšª¶J“P‡¼­Þ~initial threadšª¶JžP‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J©P‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¿P‡¼­Þ~initial threadšª¶JÊP‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÕP‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JøP‡¼­Þ~initial threadšª¶JQ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JQ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J&Q‡¼­Þ~initial threadšª¶J>Q‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JIQ‡/usr/share/nls/libc/C­Þ~initial threadšª¶J]Q‡¼­Þ~initial threadšª¶JhQ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JsQ‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JŠQ‡¼­Þ~initial threadšª¶J•Q‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J Q‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J´Q‡¼­Þ~initial threadšª¶JÂQ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÍQ‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JâQ‡¼­Þ~initial threadšª¶JíQ‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J÷Q‡/usr/share/nls/libc/C­Þ~initial threadšª¶J R‡¼­Þ~initial threadšª¶JR‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J R‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J7R‡¼­Þ~initial threadšª¶JBR‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JMR‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JaR‡¼­Þ~initial threadšª¶JnR‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J†R‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JœR‡¼­Þ~initial threadšª¶J§R‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J±R‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÅR‡¼­Þ~initial threadšª¶JÐR‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÛR‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JñR‡¼­Þ~initial threadšª¶JüR‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JS‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JS‡¼­Þ~initial threadšª¶J)S‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J4S‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JWS‡¼­Þ~initial threadšª¶JdS‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JoS‡/usr/share/nls/libc/C­Þ~initial threadšª¶JƒS‡¼­Þ~initial threadšª¶JŽS‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J™S‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¯S‡¼­Þ~initial threadšª¶JºS‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÅS‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÚS‡¼­Þ~initial threadšª¶JçS‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JòS‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JT‡¼­Þ~initial threadšª¶JT‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JT‡/usr/share/nls/libc/C­Þ~initial threadšª¶J0T‡¼­Þ~initial threadšª¶J;T‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JFT‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J\T‡¼­Þ~initial threadšª¶JgT‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JrT‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J‡T‡¼­Þ~initial threadšª¶J”T‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JŸT‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J´T‡¼­Þ~initial threadšª¶J¿T‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÊT‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÝT‡¼­Þ~initial threadšª¶JèT‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JóT‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J U‡¼­Þ~initial threadšª¶JU‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JU‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J4U‡¼­Þ~initial threadšª¶JBU‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JMU‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JbU‡¼­Þ~initial threadšª¶JmU‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JxU‡/usr/share/nls/libc/C­Þ~initial threadšª¶J‹U‡¼­Þ~initial threadšª¶J–U‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¡U‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J·U‡¼­Þ~initial threadšª¶JÂU‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÍU‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JâU‡¼­Þ~initial threadšª¶JïU‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JúU‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JV‡¼­Þ~initial threadšª¶JV‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J%V‡/usr/share/nls/libc/C­Þ~initial threadšª¶J9V‡¼­Þ~initial threadšª¶JCV‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JNV‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JdV‡¼­Þ~initial threadšª¶JpV‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JzV‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JV‡¼­Þ~initial threadšª¶JœV‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¨V‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¼V‡¼­Þ~initial threadšª¶JÈV‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÒV‡/usr/share/nls/libc/C­Þ~initial threadšª¶JæV‡¼­Þ~initial threadšª¶JñV‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JûV‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JW‡¼­Þ~initial threadšª¶JW‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J'W‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J^‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JS^‡¼­Þ~initial threadšª¶J`^‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jk^‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J€^‡¼­Þ~initial threadšª¶JŒ^‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J–^‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jª^‡¼­Þ~initial threadšª¶Jµ^‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÀ^‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÖ^‡¼­Þ~initial threadšª¶Já^‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jì^‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J_‡¼­Þ~initial threadšª¶J_‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J_‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J/_‡¼­Þ~initial threadšª¶J:_‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JE_‡/usr/share/nls/libc/C­Þ~initial threadšª¶JX_‡¼­Þ~initial threadšª¶Jd_‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jn_‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J…_‡¼­Þ~initial threadšª¶J_‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J›_‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J°_‡¼­Þ~initial threadšª¶J½_‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÈ_‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÝ_‡¼­Þ~initial threadšª¶Jé_‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jó_‡/usr/share/nls/libc/C­Þ~initial threadšª¶J`‡¼­Þ~initial threadšª¶J`‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J`‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J3`‡¼­Þ~initial threadšª¶J?`‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JI`‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J^`‡¼­Þ~initial threadšª¶Jl`‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jw`‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JŒ`‡¼­Þ~initial threadšª¶J—`‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¢`‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jµ`‡¼­Þ~initial threadšª¶JÀ`‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JË`‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jâ`‡¼­Þ~initial threadšª¶Jí`‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jø`‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J a‡¼­Þ~initial threadšª¶Ja‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J&a‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J;a‡¼­Þ~initial threadšª¶JFa‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JQa‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jda‡¼­Þ~initial threadšª¶Jpa‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J{a‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jža‡¼­Þ~initial threadšª¶J©a‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J´a‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÉa‡¼­Þ~initial threadšª¶JÖa‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jâa‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J÷a‡¼­Þ~initial threadšª¶Jb‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J b‡/usr/share/nls/libc/C­Þ~initial threadšª¶J b‡¼­Þ~initial threadšª¶J,b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J7b‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JMb‡¼­Þ~initial threadšª¶JXb‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jcb‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jxb‡¼­Þ~initial threadšª¶J…b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jb‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤b‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J¤b‡¼­Þ~initial threadšª¶J¤b‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J‘f‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¯f‡¼­Þ~initial threadšª¶J½f‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¾f‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÀf‡¼­Þ~initial threadšª¶JÁf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÁf‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/share/nls/libc/C­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶JÂf‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÂf‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JÂf‡¼­Þ~initial threadšª¶Jåh‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jñh‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Ji‡¼­Þ~initial threadšª¶Ji‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J#i‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J8i‡¼­Þ~initial threadšª¶JCi‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JNi‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jbi‡¼­Þ~initial threadšª¶Jmi‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jwi‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JŽi‡¼­Þ~initial threadšª¶J™i‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¤i‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J¹i‡¼­Þ~initial threadšª¶JÇi‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÒi‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jçi‡¼­Þ~initial threadšª¶Jòi‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jýi‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jj‡¼­Þ~initial threadšª¶Jj‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J&j‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J=j‡¼­Þ~initial threadšª¶JHj‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JSj‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jgj‡¼­Þ~initial threadšª¶Juj‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J€j‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶J•j‡¼­Þ~initial threadšª¶J j‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J«j‡/usr/share/nls/libc/C­Þ~initial threadšª¶J¿j‡¼­Þ~initial threadšª¶JÊj‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶JÔj‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jëj‡¼­Þ~initial threadšª¶Jöj‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jk‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jk‡¼­Þ~initial threadšª¶J-k‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J8k‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶JMk‡¼­Þ~initial threadšª¶JXk‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jck‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jwk‡¼­Þ~initial threadšª¶J‚k‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jk‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶J£k‡¼­Þ~initial threadšª¶J®k‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J¹k‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶JÎk‡¼­Þ~initial threadšª¶JÛk‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jæk‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jük‡¼­Þ~initial threadšª¶Jl‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jl‡/usr/share/nls/libc/C­Þ~initial threadšª¶J%l‡¼­Þ~initial threadšª¶J0l‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶J;l‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶JQl‡¼­Þ~initial threadšª¶J\l‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jfl‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶Jfl‡¼­Þ~initial threadšª¶Jfl‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jfl‡/usr/share/nls/C/libc.cat­Þ~initial threadšª¶Jfl‡¼­Þ~initial threadšª¶Jfl‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jfl‡/usr/share/nls/libc/C­Þ~initial threadšª¶Jfl‡¼­Þ~initial threadšª¶Jål‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jïl‡/usr/local/share/nls/C/libc.cat­Þ~initial threadšª¶Jm‡¼­Þ~initial threadšª¶Jm‡¼0¨ÿÿÿ°§ÿÿÿ­Þ~initial threadšª¶Jm‡/usr/local/share/nls/libc/C­Þ~initial threadšª¶J/m‡¼­Þ~initial threadšª¶Jøm‡­Þ~initial threadšª¶JÐn‡­Þ~initial threadšª¶Jao‡¼Эÿÿÿð¬ÿÿÿ:­Þ~initial threadšª¶JÁo‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/cStringIO­Þ~initial threadšª¶Jp‡¼ ­Þ~initial threadšª¶J.p‡Эÿÿÿ¶=­Þ~initial threadšª¶JKp‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/cStringIO.so­Þ~initial threadšª¶J_p‡ ­Þ~initial threadšª¶Jlp‡Эÿÿÿ¶C­Þ~initial threadšª¶Jup‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/cStringIOmodule.so­Þ~initial threadšª¶Jzp‡ ­Þ~initial threadšª¶J~p‡Эÿÿÿ¶=­Þ~initial threadšª¶Jp‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/cStringIO.py­Þ~initial threadšª¶Jƒp‡ ­Þ~initial threadšª¶J„p‡Эÿÿÿ¶>­Þ~initial threadšª¶J…p‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/cStringIO.pyc­Þ~initial threadšª¶J…p‡­Þ~initial threadšª¶J†p‡¼Эÿÿÿð¬ÿÿÿ"­Þ~initial threadšª¶J†p‡/usr/local/lib/python2.6/cStringIO­Þ~initial threadšª¶J†p‡¼ ­Þ~initial threadšª¶J†p‡Эÿÿÿ¶%­Þ~initial threadšª¶J†p‡/usr/local/lib/python2.6/cStringIO.so­Þ~initial threadšª¶J†p‡ ­Þ~initial threadšª¶J†p‡Эÿÿÿ¶+­Þ~initial threadšª¶J†p‡/usr/local/lib/python2.6/cStringIOmodule.so­Þ~initial threadšª¶J†p‡ ­Þ~initial threadšª¶J†p‡Эÿÿÿ¶%­Þ~initial threadšª¶J†p‡/usr/local/lib/python2.6/cStringIO.py­Þ~initial threadšª¶J†p‡ ­Þ~initial threadšª¶J†p‡Эÿÿÿ¶&­Þ~initial threadšª¶J†p‡/usr/local/lib/python2.6/cStringIO.pyc­Þ~initial threadšª¶J†p‡­Þ~initial threadšª¶J†p‡¼Эÿÿÿð¬ÿÿÿ0­Þ~initial threadšª¶J†p‡/usr/local/lib/python2.6/plat-freebsd8/cStringIO­Þ~initial threadšª¶J†p‡¼ ­Þ~initial threadšª¶J†p‡Эÿÿÿ¶3­Þ~initial threadšª¶J›t‡/usr/local/lib/python2.6/plat-freebsd8/cStringIO.so­Þ~initial threadšª¶Jµt‡ ­Þ~initial threadšª¶JÀt‡Эÿÿÿ¶9­Þ~initial threadšª¶JÍt‡/usr/local/lib/python2.6/plat-freebsd8/cStringIOmodule.so­Þ~initial threadšª¶Jåt‡ ­Þ~initial threadšª¶Jðt‡Эÿÿÿ¶3­Þ~initial threadšª¶Jýt‡/usr/local/lib/python2.6/plat-freebsd8/cStringIO.py­Þ~initial threadšª¶Ju‡ ­Þ~initial threadšª¶J u‡Эÿÿÿ¶4­Þ~initial threadšª¶J-u‡/usr/local/lib/python2.6/plat-freebsd8/cStringIO.pyc­Þ~initial threadšª¶JDu‡­Þ~initial threadšª¶JPu‡¼Эÿÿÿð¬ÿÿÿ)­Þ~initial threadšª¶J[u‡/usr/local/lib/python2.6/lib-tk/cStringIO­Þ~initial threadšª¶Jsu‡¼ ­Þ~initial threadšª¶J~u‡Эÿÿÿ¶,­Þ~initial threadšª¶JŠu‡/usr/local/lib/python2.6/lib-tk/cStringIO.so­Þ~initial threadšª¶J¢u‡ ­Þ~initial threadšª¶J¬u‡Эÿÿÿ¶2­Þ~initial threadšª¶J¹u‡/usr/local/lib/python2.6/lib-tk/cStringIOmodule.so­Þ~initial threadšª¶JÐu‡ ­Þ~initial threadšª¶JÜu‡Эÿÿÿ¶,­Þ~initial threadšª¶Jèu‡/usr/local/lib/python2.6/lib-tk/cStringIO.py­Þ~initial threadšª¶Jÿu‡ ­Þ~initial threadšª¶J v‡Эÿÿÿ¶-­Þ~initial threadšª¶Jv‡/usr/local/lib/python2.6/lib-tk/cStringIO.pyc­Þ~initial threadšª¶J.v‡­Þ~initial threadšª¶J.v‡¼Эÿÿÿð¬ÿÿÿ*­Þ~initial threadšª¶J.v‡/usr/local/lib/python2.6/lib-old/cStringIO­Þ~initial threadšª¶J.v‡¼ ­Þ~initial threadšª¶J.v‡Эÿÿÿ¶-­Þ~initial threadšª¶J.v‡/usr/local/lib/python2.6/lib-old/cStringIO.so­Þ~initial threadšª¶J.v‡ ­Þ~initial threadšª¶J.v‡Эÿÿÿ¶3­Þ~initial threadšª¶J.v‡/usr/local/lib/python2.6/lib-old/cStringIOmodule.so­Þ~initial threadšª¶J.v‡ ­Þ~initial threadšª¶J.v‡Эÿÿÿ¶-­Þ~initial threadšª¶J.v‡/usr/local/lib/python2.6/lib-old/cStringIO.py­Þ~initial threadšª¶J.v‡ ­Þ~initial threadšª¶J.v‡Эÿÿÿ¶.­Þ~initial threadšª¶J.v‡/usr/local/lib/python2.6/lib-old/cStringIO.pyc­Þ~initial threadšª¶J.v‡­Þ~initial threadšª¶J.v‡¼Эÿÿÿð¬ÿÿÿ.­Þ~initial threadšª¶J.v‡/usr/local/lib/python2.6/lib-dynload/cStringIO­Þ~initial threadšª¶J.v‡¼ ­Þ~initial threadšª¶J.v‡Эÿÿÿ¶1­Þ~initial threadšª¶Jew‡/usr/local/lib/python2.6/lib-dynload/cStringIO.so­Þ~initial threadšª¶J€w‡­Þ~initial threadšª¶J’w‡½À¬ÿÿÿ}­Þ~initial threadšª¶J¡w‡stat[sÎí ðª¶Jµ²Jë²Jc4µ²J­Þ~initial threadšª¶J«w‡½ ­Þ~initial threadšª¶J·w‡Tà sªÿÿÿ­Þ~initial threadšª¶JÂw‡T ­Þ~initial threadšª¶JÐw‡€Dc21­Þ~initial threadšª¶JÝw‡/usr/local/lib/python2.6/lib-dynload/cStringIO.so­Þ~initial threadšª¶Jõw‡­Þ~initial threadšª¶Jx‡½€©ÿÿÿ}­Þ~initial threadšª¶J x‡stat[sÎí ðª¶Jµ²Jë²Jc4µ²J­Þ~initial threadšª¶Jx‡½ ­Þ~initial threadšª¶J!x‡à¡s­Þ~initial threadšª¶J7x‡ELF >à@øG@8@œ.œ.000¸À˜C˜C˜CPåtd”.”.”.CIHD>6 G"2@0-,A$5%<#+1*3/;'!4?E)BC:F&.(87=9 X0 , À àÈ Ü à X, h, ”.0@˜C(E8EHEPE¸FT¥^³ƒñÿ˜Cm,"1OÜ| àót(ü È݇Íöb­L1ó¹¢[>âñÿ¸Fœ?& X,»0‘uНÛñÿ¸F7J ñÿPEîñÿÀFñvÆ­O%; _DYNAMIC_GLOBAL_OFFSET_TABLE__init_fini__cxa_finalize_Jv_RegisterClasses_Py_ZeroStruct_Py_TrueStruct_Py_NoneStructinitcStringIOPy_InitModule4_64PyModule_GetDictPyType_TypePyType_ReadyPyCObject_FromVoidPtrPyDict_SetItemStringfreePyExc_ValueErrorPyErr_SetStringPyArg_ParseTuplereallocPyErr_NoMemoryPyTuple_Size__errorPyExc_IOErrorPyErr_SetFromErrnoPyInt_FromSsize_tPyString_FromStringAndSizePyList_NewPyList_AppendPyArg_UnpackTuplePyObject_IsTruePyObject_AsReadBufferPyExc_TypeErrorPyErr_Format_PyObject_NewmallocPyExc_MemoryErrormemcpyPyObject_GetIterPyIter_NextPyString_AsStringAndSizePyErr_OccurredPyObject_FreePyExc_StopIterationPyErr_SetNonePyObject_SelfIterlibthr.so.3libc.so.7_edata__bss_start_endFBSD_1.0Å °(zóѰ(zó000@E`8º,h8À(x8@3 8ð"¨8p"°80)¸8%À8(È8€'Ð8à<Ø8€>à8|-è8#ø849‚-9ð&9@4 9‹-(9`#89­Þ~initial threadšª¶J}x‡8­Þ~initial threadšª¶J‰x‡ÝPÿÿÿÿ­Þ~initial threadšª¶J›x‡ÝÀp8­Þ~initial threadšª¶J¦x‡ÝÀp0­Þ~initial threadšª¶JÂx‡ÝÀp8­Þ~initial threadšª¶JÍx‡Ýð€ 0­Þ~initial threadšª¶Jïx‡Ýð€­Þ~initial threadšª¶J&y‡­Þ~initial threadšª¶J3y‡8­Þ~initial threadšª¶JCy‡Ýÿÿÿÿ­Þ~initial threadšª¶JPy‡Ýc­Þ~initial threadšª¶J‹y‡Ic­Þ~initial threadšª¶Jïy‡I ­Þ~initial threadšª¶Jz‡Tð s­Þ~initial threadšª¶Jz‡T ­Þ~initial threadšª¶J.z‡Tà sЩÿÿÿ­Þ~initial threadšª¶J9z‡T ­Þ~initial threadšª¶JDz‡Tð s­Þ~initial threadšª¶J\z‡T­Þ~initial threadšª¶J”z‡­Þ~initial threadšª¶J¢z‡­Þ~initial threadšª¶J⇭Þ~initial threadšª¶Jò‡­Þ~initial threadšª¶J9€‡¼°Àÿÿÿпÿÿÿ.­Þ~initial threadšª¶JF€‡/usr/local/lib/python2.6/site-packages/pcs/pcs­Þ~initial threadšª¶Jb€‡¼ ­Þ~initial threadšª¶Jn€‡°Àÿÿÿ¶1­Þ~initial threadšª¶Jz€‡/usr/local/lib/python2.6/site-packages/pcs/pcs.so­Þ~initial threadšª¶J”€‡ ­Þ~initial threadšª¶JŸ€‡°Àÿÿÿ¶7­Þ~initial threadšª¶J¬€‡/usr/local/lib/python2.6/site-packages/pcs/pcsmodule.so­Þ~initial threadšª¶JÅ€‡ ­Þ~initial threadšª¶JЀ‡°Àÿÿÿ¶1­Þ~initial threadšª¶JÝ€‡/usr/local/lib/python2.6/site-packages/pcs/pcs.py­Þ~initial threadšª¶Jö€‡ ­Þ~initial threadšª¶J‡°Àÿÿÿ¶2­Þ~initial threadšª¶J‡/usr/local/lib/python2.6/site-packages/pcs/pcs.pyc­Þ~initial threadšª¶J'‡­Þ~initial threadšª¶J7‡¼°Àÿÿÿпÿÿÿ/­Þ~initial threadšª¶JC‡/usr/local/lib/python2.6/site-packages/pcs/pcap­Þ~initial threadšª¶J\‡¼ ­Þ~initial threadšª¶Jg‡°Àÿÿÿ¶2­Þ~initial threadšª¶Js‡/usr/local/lib/python2.6/site-packages/pcs/pcap.so­Þ~initial threadšª¶Jއ­Þ~initial threadšª¶Jœ‡½ ¿ÿÿÿ}­Þ~initial threadšª¶J¨‡stat[*ˆí¸Hª¶Jtª¶Jtª¶JY¿àtª¶J­Þ~initial threadšª¶J²‡½ ­Þ~initial threadšª¶J½‡Tà sà¼ÿÿÿ­Þ~initial threadšª¶JLJT ­Þ~initial threadšª¶JÒ‡ÀDc32­Þ~initial threadšª¶JÞ‡/usr/local/lib/python2.6/site-packages/pcs/pcap.so­Þ~initial threadšª¶Jù‡­Þ~initial threadšª¶J‚‡½`¼ÿÿÿ}­Þ~initial threadšª¶J‚‡stat[*ˆí¸Hª¶Jtª¶Jtª¶JY¿àtª¶J­Þ~initial threadšª¶J‚‡½ ­Þ~initial threadšª¶J$‚‡à¡s­Þ~initial threadšª¶J5‚‡ELF >ÀN@d@8@$)$)000 2¸9]]]  Påtd)))ƒ™MKƒ~>]1’jNSFp–fŽ˜Y(=<\s€e…gw6RZ‘[‚:'2y*)—“†tlVJ90„P5|‡u•oŠB}z{.bv”ncx`ˆAŒ‰"$ ,%!48C7&D/#HI^TLhWQX-+?;UiadGOkE@q3‹mr_ ˜ð @€@?pH „H ÀN h  x  )0xU]¨^¸^È^Ð^ b¶'ðù{  1eÃ88tЇ ñÿ]oƒ"ðµü¾ŽŠ ‡U÷7O,"1ÒHgúRѵ‰ p © Е&ÒÁuÂ{ @Cv €Ðñ –Á pH±i  ñ«/ŽwP‹*!B `â^!´áÞqEãø&f`iBQV R‰wñÿ b®‰*z}®­Þ~initial threadšª¶JA‚‡8­Þ~initial threadšª¶JL‚‡Ýpÿÿÿÿ­Þ~initial threadšª¶JX‚‡Ý8­Þ~initial threadšª¶Jb‚‡Ý0­Þ~initial threadšª¶J—‚‡Ý8­Þ~initial threadšª¶J¢‚‡Ý@’@0­Þ~initial threadšª¶J¼‚‡Ý@’­Þ~initial threadšª¶Jß‚‡­Þ~initial threadšª¶J삇­Þ~initial threadšª¶Jü‚‡!Pc­Þ~initial threadšª¶J ƒ‡/lib/libpcap.so.7­Þ~initial threadšª¶Jƒ‡! ­Þ~initial threadšª¶J*ƒ‡à*c²s­Þ~initial threadšª¶J6ƒ‡/lib/libpcap.so.7­Þ~initial threadšª¶JGƒ‡­Þ~initial threadšª¶JQƒ‡½@¼ÿÿÿ}­Þ~initial threadšª¶J]ƒ‡statY)$0`ª¶JXµJXµJ€XµJ­Þ~initial threadšª¶Jgƒ‡½ ­Þ~initial threadšª¶Jrƒ‡à¡s­Þ~initial threadšª¶Jƒƒ‡ELF >`l@ú@8@¬Á¬ÁÀÁÀÁÀÁø4hAàíàíàíPåtd¤Á¤Á¤Á*Kž¹ÞèX£bÌv œy¿> »u,xÙNíPº ýGæ6§5 %ë÷2ùž! ÂåØ×äHµ)(¼†ã<YFÛ¶`á·”õtÔòÖà›ZSd¥#¤9Æeû½â±ÏÒ|Îö¡ ç¸Á'ì4TÖ‹=Ü"Ñši&øo‡“þz\ÓóJÈêÚŽÕ$fÊ&ªßé’°­Ä"MÿkrsË#!;/+A:B'%mL7n{~ClQUj‰.gˆaE]_‚—W}^¬¯3pI´Œ0•w«ÇV͘‘™R„O³É®€ÝÐ ©Dh@1Ÿƒî…-?ðc$À(üï[ñ¦²Šúqô* ¨8)¢ ð à% 3ø56QPa da `l ¨° À° ¤ÁÀÁðÎàípï€ïï˜ïÀöì Є'g  é3`øiÒ¬ - ¤  €„ l  `y§n  ‰7Ê 0ô5  PÞJ ýN± ððQß  °}QC  ­Õ°    ƒ º  0ƒ¿ `£D<Jü  €‹"ð  `ƒbi  ¨Ópì  À€W pο˜ €“"Á  Çë ÀŽt® °z  °‹­6  ~©‡ ðßN  Ѓ ù`ñÿàíq €Rà àžag ð£3  @/)  ÀŒ­Þ~initial threadšª¶J¼ƒ‡8­Þ~initial threadšª¶Jǃ‡Ýÿÿÿÿ­Þ~initial threadšª¶JÓƒ‡Ý€’8­Þ~initial threadšª¶JÞƒ‡Ý€’ЭÞ~initial threadšª¶JI„‡Ý€’8­Þ~initial threadšª¶JU„‡Ý@¥@À­Þ~initial threadšª¶Jm„‡Ý@¥ ­Þ~initial threadšª¶Jš„‡J€¥­Þ~initial threadšª¶J¨„‡J­Þ~initial threadšª¶J»„‡­Þ~initial threadšª¶JÈ„‡8­Þ~initial threadšª¶JÖ„‡Ý ÿÿÿÿ­Þ~initial threadšª¶JㄇÝc­Þ~initial threadšª¶Jy…‡Ic ­Þ~initial threadšª¶JÌ…‡I8­Þ~initial threadšª¶J†‡Ý ÿÿÿÿ­Þ~initial threadšª¶J%†‡Ýc­Þ~initial threadšª¶J„†‡Ic ­Þ~initial threadšª¶JÖ†‡I ­Þ~initial threadšª¶Jò‡‡Tð s­Þ~initial threadšª¶Jý‡‡T ­Þ~initial threadšª¶J ˆ‡Tà s°¼ÿÿÿ­Þ~initial threadšª¶Jˆ‡T ­Þ~initial threadšª¶J"ˆ‡Tð s­Þ~initial threadšª¶J,ˆ‡T ­Þ~initial threadšª¶J:ˆ‡Tà s°¼ÿÿÿ­Þ~initial threadšª¶JEˆ‡T ­Þ~initial threadšª¶JOˆ‡Tð s­Þ~initial threadšª¶JYˆ‡T­Þ~initial threadšª¶J¶ˆ‡¼µÿÿÿ ´ÿÿÿ4­Þ~initial threadšª¶Jȇ/usr/home/gnn/Personal/Code/Networking/PCS/tests/bpf­Þ~initial threadšª¶J∇¼ ­Þ~initial threadšª¶Jµÿÿÿ¶7­Þ~initial threadšª¶J‰‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/bpf.so­Þ~initial threadšª¶J ‰‡ ­Þ~initial threadšª¶J,‰‡µÿÿÿ¶=­Þ~initial threadšª¶J7‰‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/bpfmodule.so­Þ~initial threadšª¶JT‰‡ ­Þ~initial threadšª¶J_‰‡µÿÿÿ¶7­Þ~initial threadšª¶Jk‰‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/bpf.py­Þ~initial threadšª¶J‡‰‡ ­Þ~initial threadšª¶J’‰‡µÿÿÿ¶8­Þ~initial threadšª¶Jž‰‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/bpf.pyc­Þ~initial threadšª¶J¸‰‡­Þ~initial threadšª¶J¸‰‡¼µÿÿÿ ´ÿÿÿ­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/bpf­Þ~initial threadšª¶J¸‰‡¼ ­Þ~initial threadšª¶J¸‰‡µÿÿÿ¶­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/bpf.so­Þ~initial threadšª¶J¸‰‡ ­Þ~initial threadšª¶J¸‰‡µÿÿÿ¶%­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/bpfmodule.so­Þ~initial threadšª¶J¸‰‡ ­Þ~initial threadšª¶J¸‰‡µÿÿÿ¶­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/bpf.py­Þ~initial threadšª¶J¸‰‡ ­Þ~initial threadšª¶J¸‰‡µÿÿÿ¶ ­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/bpf.pyc­Þ~initial threadšª¶J¸‰‡­Þ~initial threadšª¶J¸‰‡¼µÿÿÿ ´ÿÿÿ*­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/plat-freebsd8/bpf­Þ~initial threadšª¶J¸‰‡¼ ­Þ~initial threadšª¶J¸‰‡µÿÿÿ¶-­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/plat-freebsd8/bpf.so­Þ~initial threadšª¶J¸‰‡ ­Þ~initial threadšª¶J¸‰‡µÿÿÿ¶3­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/plat-freebsd8/bpfmodule.so­Þ~initial threadšª¶J¸‰‡ ­Þ~initial threadšª¶J¸‰‡µÿÿÿ¶-­Þ~initial threadšª¶J¸‰‡/usr/local/lib/python2.6/plat-freebsd8/bpf.py­Þ~initial threadšª¶JX‹‡ ­Þ~initial threadšª¶Jc‹‡µÿÿÿ¶.­Þ~initial threadšª¶Jo‹‡/usr/local/lib/python2.6/plat-freebsd8/bpf.pyc­Þ~initial threadšª¶J†‹‡­Þ~initial threadšª¶J’‹‡¼µÿÿÿ ´ÿÿÿ#­Þ~initial threadšª¶J¦‹‡/usr/local/lib/python2.6/lib-tk/bpf­Þ~initial threadšª¶J¾‹‡¼ ­Þ~initial threadšª¶JÉ‹‡µÿÿÿ¶&­Þ~initial threadšª¶JÕ‹‡/usr/local/lib/python2.6/lib-tk/bpf.so­Þ~initial threadšª¶J틇 ­Þ~initial threadšª¶Jø‹‡µÿÿÿ¶,­Þ~initial threadšª¶JŒ‡/usr/local/lib/python2.6/lib-tk/bpfmodule.so­Þ~initial threadšª¶JŒ‡ ­Þ~initial threadšª¶J'Œ‡µÿÿÿ¶&­Þ~initial threadšª¶J3Œ‡/usr/local/lib/python2.6/lib-tk/bpf.py­Þ~initial threadšª¶JKŒ‡ ­Þ~initial threadšª¶JVŒ‡µÿÿÿ¶'­Þ~initial threadšª¶JbŒ‡/usr/local/lib/python2.6/lib-tk/bpf.pyc­Þ~initial threadšª¶JzŒ‡­Þ~initial threadšª¶J…Œ‡¼µÿÿÿ ´ÿÿÿ$­Þ~initial threadšª¶JŒ‡/usr/local/lib/python2.6/lib-old/bpf­Þ~initial threadšª¶J§Œ‡¼ ­Þ~initial threadšª¶J²Œ‡µÿÿÿ¶'­Þ~initial threadšª¶J¾Œ‡/usr/local/lib/python2.6/lib-old/bpf.so­Þ~initial threadšª¶JÖŒ‡ ­Þ~initial threadšª¶Jጇµÿÿÿ¶-­Þ~initial threadšª¶J팇/usr/local/lib/python2.6/lib-old/bpfmodule.so­Þ~initial threadšª¶J‡ ­Þ~initial threadšª¶J‡µÿÿÿ¶'­Þ~initial threadšª¶J‡/usr/local/lib/python2.6/lib-old/bpf.py­Þ~initial threadšª¶J4‡ ­Þ~initial threadšª¶J?‡µÿÿÿ¶(­Þ~initial threadšª¶JK‡/usr/local/lib/python2.6/lib-old/bpf.pyc­Þ~initial threadšª¶Jc‡­Þ~initial threadšª¶Jo‡¼µÿÿÿ ´ÿÿÿ(­Þ~initial threadšª¶Jy‡/usr/local/lib/python2.6/lib-dynload/bpf­Þ~initial threadšª¶J‘‡¼ ­Þ~initial threadšª¶J›‡µÿÿÿ¶+­Þ~initial threadšª¶J¨‡/usr/local/lib/python2.6/lib-dynload/bpf.so­Þ~initial threadšª¶JÀ‡ ­Þ~initial threadšª¶Jˇµÿÿÿ¶1­Þ~initial threadšª¶Jð‡/usr/local/lib/python2.6/lib-dynload/bpfmodule.so­Þ~initial threadšª¶J އ ­Þ~initial threadšª¶Jއµÿÿÿ¶+­Þ~initial threadšª¶J އ/usr/local/lib/python2.6/lib-dynload/bpf.py­Þ~initial threadšª¶J8އ ­Þ~initial threadšª¶JCއµÿÿÿ¶,­Þ~initial threadšª¶JOއ/usr/local/lib/python2.6/lib-dynload/bpf.pyc­Þ~initial threadšª¶Jyއ­Þ~initial threadšª¶J…އ¼µÿÿÿ ´ÿÿÿ*­Þ~initial threadšª¶Jއ/usr/local/lib/python2.6/site-packages/bpf­Þ~initial threadšª¶J¨Ž‡¼ ­Þ~initial threadšª¶J³Ž‡µÿÿÿ¶-­Þ~initial threadšª¶J¿Ž‡/usr/local/lib/python2.6/site-packages/bpf.so­Þ~initial threadšª¶J׎‡ ­Þ~initial threadšª¶J⎇µÿÿÿ¶3­Þ~initial threadšª¶J/usr/local/lib/python2.6/site-packages/bpfmodule.so­Þ~initial threadšª¶J‡ ­Þ~initial threadšª¶J‡µÿÿÿ¶-­Þ~initial threadšª¶J‡/usr/local/lib/python2.6/site-packages/bpf.py­Þ~initial threadšª¶J4‡ ­Þ~initial threadšª¶J@‡µÿÿÿ¶.­Þ~initial threadšª¶JL‡/usr/local/lib/python2.6/site-packages/bpf.pyc­Þ~initial threadšª¶Jd‡­Þ~initial threadšª¶J„‡­Þ~initial threadšª¶J‘‡­Þ~initial threadšª¶J³‡­Þ~initial threadšª¶JÁ‡ ­Þ~initial threadšª¶Jò‡àWO#+­Þ~initial threadšª¶J"‡Traceback (most recent call last): ­Þ~initial threadšª¶J-‡# ­Þ~initial threadšª¶J;‡pÜÿÿÿ-5­Þ~initial threadšª¶JI‡ File "boundstest.py", line 49, in ­Þ~initial threadšª¶JS‡- ­Þ~initial threadšª¶J^‡¤Áܶ ­Þ~initial threadšª¶Jj‡boundstest.py­Þ~initial threadšª¶J{‡­Þ~initial threadšª¶J‡‡½ÐÎÿÿÿ}­Þ~initial threadšª¶J”‡stat[u™´éé:(šª¶J”•¶J”•¶J­ ”•¶J­Þ~initial threadšª¶Jž‡½ ­Þ~initial threadšª¶Jª‡`ß­Þ~initial threadšª¶J¼‡# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id:$ # # Author: George V. Neville-Neil # # Description: A simple test of all the bound checking code in PCS import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs from pcs.packets.ipv4 import * from pcs.packets.ethernet import * from pcs.packets.dns import * class boundaryPacket(pcs.Packet): """Define a packet full of bit fields for use in testing. """ _layout = pcs.Layout() def __init__(self, bytes = None): f1 = pcs.Field("f1", 1) f2 = pcs.Field("f2", 2) f3 = pcs.Field("f3", 3) f4 = pcs.Field("f4", 4) f5 = pcs.Field("f5", 5) f6 = pcs.Field("f6", 6) f7 = pcs.Field("f7", 7) f8 = pcs.Field("f8", 8) f9 = pcs.Field("f9", 9) f10 = pcs.Field("f10", 10) f11 = pcs.Field("f11", 11) f12 = pcs.Field("f12", 12) f13 = pcs.Field("f13", 13) f14 = pcs.Field("f14", 14) f15 = pcs.Field("f15", 15) f16 = pcs.Field("f16", 16) f17 = pcs.Field("f17", 17) f18 = pcs.Field("f18", 18) f19 = pcs.Field("f19", 19) f20 = pcs.Field("f20", 20) f21 = pcs.Field("f21", 21) f22 = pcs.Field("f22", 22) f23 = pcs.Field("f23", 23) f24 = pcs.Field("f24", 24) f25 = pcs.Field("f25", 25) f26 = pcs.Field("f26", 26) f27 = pcs.Field("f27", 27) f28 = pcs.Field("f28", 28) f29 = pcs.Field("f29", 29) f30 = pcs.Field("f30", 30) f31 = pcs.Field("f31", 31) f32 = pcs.Field("f32", 32) pcs.Packet.__init__(self, [f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, f18, f19, f20, f21, f22, f23, f24, f25, f26, f27, f28, f29, f30, f31, f32], bytes = None) class boundsTestCase(unittest.TestCase): def test_field(self): ip = ipv4() assert (ip != None) self.assertRaises(pcs.FieldBoundsError, setattr, ip, 'version', 9999) def test_stringfield(self): ether = ethernet() self.assertRaises(pcs.FieldBoundsError, setattr, ether, 'src', "\x00\x00\x00\x00\x00\x00\x00") def test_lengthvaluefield(self): ­Þ~initial threadšª¶Jþ‡ ­Þ~initial threadšª¶J‘‡Üÿÿÿ ­Þ~initial threadšª¶J!‘‡ ­Þ~initial threadšª¶J+‘‡ ­Þ~initial threadšª¶J6‘‡4Ðÿÿÿ ­Þ~initial threadšª¶JC‘‡import pcs ­Þ~initial threadšª¶JM‘‡ ­Þ~initial threadšª¶JX‘‡­Þ~initial threadšª¶Jl‘‡ ­Þ~initial threadšª¶J{‘‡pÜÿÿÿV^­Þ~initial threadšª¶J‰‘‡ File "/usr/local/lib/python2.6/site-packages/pcs/__init__.py", line 68, in ­Þ~initial threadšª¶J”‘‡V ­Þ~initial threadšª¶JŸ‘‡ô+ã¶6­Þ~initial threadšª¶J«‘‡/usr/local/lib/python2.6/site-packages/pcs/__init__.py­Þ~initial threadšª¶JÇ‘‡­Þ~initial threadšª¶JÓ‘‡½ÐÎÿÿÿ}­Þ~initial threadšª¶Jß‘‡stat[󇤪¶J”•¶Jtª¶J‘‚Ä”•¶J­Þ~initial threadšª¶J鑇½ ­Þ~initial threadšª¶Jõ‘‡`ß­Þ~initial threadšª¶J’‡# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: __init__.py,v 1.9 2006/09/05 07:30:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A packet module for Python. We will package the # individual protocols separately. """PCS aka Packet Construction Set PCS is a set of Python modules and objects that make building network protocol testing tools easier for the protocol developer. The core of the system is the pcs module itself which provides the necessary functionality to create classes that implement packets. In PCS every packet is a class and the layout of the packet is defined by a Layout class which contains a set of Fields. Fields can be from 1 to many bits, so it is possible to build packets with arbitrary width bit fields. Fields know about the widths and will throw exceptions when they are overloaded. Every Packet object, that is an object instantiated from a specific PCS packet class, has a field named bytes which shows the representation of the data in the packet at that point in time. It is the bytes field that is used when transmitting the packet on the wire. For more information please see the manual, called pcs, and available in various formats after installation. """ __revision__ = "$Id: __init__.py,v 1.9 2006/09/05 07:30:56 gnn Exp $" # We need the struct module to pack our class into a byte string. import struct # We need the socket module for to implement some of the Connector classes. from socket import * import pcs.pcap as pcap import exceptions import itertools # import fast def attribreprlist(obj, attrs): return map(lambda x, y = obj: '%s: %s' % (x.name, repr(getattr(y, x.name))), itertools.ifilter(lambda x, y = obj: hasattr(y, x.name), attrs)) class FieldBoundsError(Exception): """When a programmer tries to set a field with an inappropriately sized piece of data this exception is raised.""" def __init__(self, message): self.message = message def __str__(self): return repr(self.message) # XXX Should really be named IntegerField and the common methods shuffled # off into a base class. class Field(object): """A field is a name, a type, a width in bits, possibly a default value and can be marked as a dicriminator for higher level packet demultiplexing . These classes are used by the packet to define the layout of the data and how it is addressed.""" def __init__(self, name = "", width = 1, default = None, discriminator = False, compare=None): """initialize a field name - a string name width - a wid­Þ~initial threadšª¶J’‡ ­Þ~initial threadšª¶J*’‡Üÿÿÿ ­Þ~initial threadšª¶J8’‡ ­Þ~initial threadšª¶JB’‡ ­Þ~initial threadšª¶JL’‡0Ðÿÿÿ ­Þ~initial threadšª¶JZ’‡import pcs.pcap as pcap ­Þ~initial threadšª¶Jd’‡­Þ~initial threadšª¶Jo’‡­Þ~initial threadšª¶JŠ’‡ ­Þ~initial threadšª¶J˜’‡pÜÿÿÿ:B­Þ~initial threadšª¶J¦’‡ File "bpf.pxd", line 33, in pcap (pcs/pcap/pcap.c:4840) ­Þ~initial threadšª¶Jº’‡: ­Þ~initial threadšª¶JÅ’‡ÄUä¶­Þ~initial threadšª¶JÑ’‡bpf.pxd­Þ~initial threadšª¶JÞ’‡ ­Þ~initial threadšª¶Jë’‡Øÿÿÿ¶8­Þ~initial threadšª¶J÷’‡/usr/home/gnn/Personal/Code/Networking/PCS/tests/bpf.pxd­Þ~initial threadšª¶J“‡ ­Þ~initial threadšª¶J!“‡Øÿÿÿ¶#­Þ~initial threadšª¶J-“‡/usr/local/lib/python26.zip/bpf.pxd­Þ~initial threadšª¶JB“‡ ­Þ~initial threadšª¶JM“‡Øÿÿÿ¶ ­Þ~initial threadšª¶JY“‡/usr/local/lib/python2.6/bpf.pxd­Þ~initial threadšª¶Jo“‡ ­Þ~initial threadšª¶Jz“‡Øÿÿÿ¶.­Þ~initial threadšª¶Jz“‡/usr/local/lib/python2.6/plat-freebsd8/bpf.pxd­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡Øÿÿÿ¶'­Þ~initial threadšª¶Jz“‡/usr/local/lib/python2.6/lib-tk/bpf.pxd­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡Øÿÿÿ¶(­Þ~initial threadšª¶Jz“‡/usr/local/lib/python2.6/lib-old/bpf.pxd­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡Øÿÿÿ¶,­Þ~initial threadšª¶Jz“‡/usr/local/lib/python2.6/lib-dynload/bpf.pxd­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡Øÿÿÿ¶.­Þ~initial threadšª¶Jz“‡/usr/local/lib/python2.6/site-packages/bpf.pxd­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡ÉèM ­Þ~initial threadšª¶Jz“‡ImportError­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡N ­Þ~initial threadšª¶Jz“‡: ­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡ÔÏâ­Þ~initial threadšª¶Jz“‡No module named bpf­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡ÿM ­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡ ­Þ~initial threadšª¶Jz“‡ ðåÿÿÿÐåÿÿÿ­Þ~initial threadšª¶Jz“‡  ­Þ~initial threadšª¶J8‡Tà sÐæÿÿÿ­Þ~initial threadšª¶J8‡T ­Þ~initial threadšª¶J8‡Tð s­Þ~initial threadšª¶Jm‡T ­Þ~initial threadšª¶Jx‡Tà s€æÿÿÿ­Þ~initial threadšª¶J‚‡T ­Þ~initial threadšª¶JŒ‡Tð s­Þ~initial threadšª¶J–‡T ­Þ~initial threadšª¶J¡‡Tà s€æÿÿÿ­Þ~initial threadšª¶J«‡T ­Þ~initial threadšª¶Jµ‡Tð s­Þ~initial threadšª¶J¿‡T ­Þ~initial threadšª¶JɇTà s€æÿÿÿ­Þ~initial threadšª¶JÓ‡T ­Þ~initial threadšª¶J݇Tð s­Þ~initial threadšª¶Jç‡T ­Þ~initial threadšª¶Jñ‡Tà s€æÿÿÿ­Þ~initial threadšª¶Jû‡T ­Þ~initial threadšª¶Jž‡Tð s­Þ~initial threadšª¶Jž‡T ­Þ~initial threadšª¶Jž‡Tà s€æÿÿÿ­Þ~initial threadšª¶J$ž‡T ­Þ~initial threadšª¶J.ž‡Tð s­Þ~initial threadšª¶J7ž‡T ­Þ~initial threadšª¶JCž‡Tà s€æÿÿÿ­Þ~initial threadšª¶JLž‡T ­Þ~initial threadšª¶JVž‡Tð s­Þ~initial threadšª¶J`ž‡T ­Þ~initial threadšª¶Jkž‡Tà s€æÿÿÿ­Þ~initial threadšª¶Jtž‡T ­Þ~initial threadšª¶J~ž‡Tð s­Þ~initial threadšª¶Jˆž‡T ­Þ~initial threadšª¶J“ž‡Tà s€æÿÿÿ­Þ~initial threadšª¶Jž‡T ­Þ~initial threadšª¶J¦ž‡Tð s­Þ~initial threadšª¶J°ž‡T ­Þ~initial threadšª¶Jºž‡Tà s€æÿÿÿ­Þ~initial threadšª¶JÅž‡T ­Þ~initial threadšª¶JΞ‡Tð s­Þ~initial threadšª¶JØž‡T ­Þ~initial threadšª¶J垇Tà s€æÿÿÿ­Þ~initial threadšª¶JT ­Þ~initial threadšª¶J>Ÿ‡Tð s­Þ~initial threadšª¶JIŸ‡T ­Þ~initial threadšª¶JUŸ‡Tà s€æÿÿÿ­Þ~initial threadšª¶J`Ÿ‡T ­Þ~initial threadšª¶JjŸ‡Tð s­Þ~initial threadšª¶JsŸ‡T ­Þ~initial threadšª¶JŸ‡Tà s€æÿÿÿ­Þ~initial threadšª¶J‰Ÿ‡T ­Þ~initial threadšª¶J“Ÿ‡Tð s­Þ~initial threadšª¶JŸ‡T ­Þ~initial threadšª¶J¨Ÿ‡Tà s€æÿÿÿ­Þ~initial threadšª¶J±Ÿ‡T ­Þ~initial threadšª¶J»Ÿ‡Tð s­Þ~initial threadšª¶JÅŸ‡T­Þ~initial threadšª¶JñŸ‡pcs-0.6/tests/loopping.out0000664000175000017500000000121011255512624015501 0ustar andreasandreas¡²ÃÔÿBøs­ ïXXETæ»@ì†[FBøs­ }  !"#$%&'()*+,-./01234567Bøs­ XXETæ¼@ô†[FBøs­ }  !"#$%&'()*+,-./01234567Bøs® ýXXETç@á>[FBøs® à  !"#$%&'()*+,-./01234567Bøs® 4XXETç@é>[FBøs® à  !"#$%&'()*+,-./01234567Bøs¯ ¬XXETçO@à†[FBøs¯ y  !"#$%&'()*+,-./01234567Bøs¯ ßXXETçP@è†[FBøs¯ y  !"#$%&'()*+,-./01234567pcs-0.6/tests/ipv4test.py0000664000175000017500000002172311255512624015270 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ipv4test.py,v 1.6 2006/08/01 13:35:58 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on the IPv4 packet. # That is to say it first encodes a packet, then decodes it and makes # sure that the data matches. import unittest import sys from hexdumper import hexdumper if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import PcapConnector from pcs.packets.ipv4 import * from pcs import inet_atol class ipTestCase(unittest.TestCase): def test_ipv4(self): # create one packet, copy its bytes, then compare their fields ip = ipv4() assert (ip != None) ip.version = 4 ip.hlen = 5 ip.tos = 0 ip.length = 64 ip.id = 1 ip.flags = 1 ip.offset = 2 ip.ttl = 33 ip.protocol = 6 ip.src = 2130706433 ip.dst = 2130706433 # Create a packet to compare against ipnew = ipv4() ipnew.decode(ip.bytes) self.assertEqual(ip.bytes, ipnew.bytes, "bytes not equal") for field in ip._fieldnames: self.assertEqual(getattr(ip, field), getattr(ipnew, field), ("%s not equal" % field)) def test_ipv4_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = PcapConnector("loopping.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) self.assertEqual(ip.version, 4, "version not equal %d" % ip.version) self.assertEqual(ip.hlen, 5, "hlen not equal %d" % ip.hlen) self.assertEqual(ip.tos, 0, "tos not equal %d" % ip.tos) self.assertEqual(ip.length, 84, "length not equal %d" % ip.length) self.assertEqual(ip.id, 59067, "id not equal %d" % ip.id) self.assertEqual(ip.flags, 0, "flags not equal %d" % ip.flags) self.assertEqual(ip.offset, 0, "offset not equal %d" % ip.offset) self.assertEqual(ip.ttl, 64, "ttl not equal %d" % ip.ttl) self.assertEqual(ip.protocol, 1, "protocol not equal %d" % ip.protocol) self.assertEqual(ip.src, inet_atol("127.0.0.1"), "src not equal %d" % ip.src) self.assertEqual(ip.dst, inet_atol("127.0.0.1"), "dst not equal %d" % ip.dst) def test_ipv4_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("loopping.out") packet = file.readpkt() ip1 = packet.data ip2 = ipv4(packet.data.bytes) assert (ip1 != None) assert (ip2 != None) self.assertEqual(ip1, ip2, "packets should be equal but are not") ip1.dst = 0xffffffffL self.assertNotEqual(ip1, ip2, "packets compare equal but should not") def test_ipv4_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("loopping.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) expected = "IPv4\nversion 4\nhlen 5\ntos 0\nlength 84\n" \ "id 59067\nflags 0\noffset 0\nttl 64\nprotocol 1\n" \ "checksum 0\nsrc 127.0.0.1\ndst 127.0.0.1\n" \ "options []\n" gotttted = ip.__str__() self.assertEqual(expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted)) def test_ipv4_println(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("loopping.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) expected = "" gotttted = ip.println() self.assertEqual(expected, gotttted, "strings are not equal \nexpected %s \ngotttted %s " % (expected, gotttted)) def test_ipv4_time(self): """Test the timestamp setting facility.""" import time file = PcapConnector("loopping.out") packet = file.readpkt() ip = packet.data self.assertEqual(packet.timestamp, ip.timestamp, "lower and upper layer timestamps are different but should not be") def test_ipv4_ra(self): # create one packet with the IP Router Alert option, # and check that it is as you'd expect. ip = ipv4() assert (ip != None) ip.version = 4 ip.hlen = 6 # XXX We add an IP option below. ip.tos = 0 ip.length = 24 # a bare IP header w/o data ip.id = 1 ip.flags = IP_DF ip.offset = 0 ip.ttl = 1 ip.protocol = 2 # a fake IGMP packet ip.src = inet_atol("192.0.2.1") ip.dst = inet_atol("224.0.0.22") # Add Router Alert option. # hlen should, in fact, be 6 words after adding a single RA option. ip.options.append(ipv4opt(IPOPT_RA)) ip.calc_checksum() #hd = hexdumper() #print hd.dump(ip.bytes) expected = "\x46\x00\x00\x18\x00\x01\x40\x00" \ "\x01\x02\x42\xC7\xC0\x00\x02\x01" \ "\xE0\x00\x00\x16\x94\x04\x00\x00" gotttted = ip.bytes self.assertEqual(expected, gotttted, "packet bytes not expected") def test_IN_LINKLOCAL(self): linklocal = inet_atol("169.254.12.34") self.assert_(IN_LINKLOCAL(linklocal) == True) non_linklocal = inet_atol("127.0.0.0") self.assert_(IN_LINKLOCAL(non_linklocal) == False) def test_IN_MULTICAST(self): mcast = inet_atol("239.0.12.34") self.assert_(IN_MULTICAST(mcast) == True) non_mcast = inet_atol("10.3.4.5") self.assert_(IN_MULTICAST(non_mcast) == False) def test_IN_LOCAL_GROUP(self): localgroup = inet_atol("224.0.0.251") self.assert_(IN_LOCAL_GROUP(localgroup) == True) nonlocalgroup = inet_atol("239.0.12.34") self.assert_(IN_LOCAL_GROUP(nonlocalgroup) == False) def test_IN_EXPERIMENTAL(self): classe = inet_atol("240.1.2.3") self.assert_(IN_EXPERIMENTAL(classe) == True) non_classe = inet_atol("30.40.50.60") self.assert_(IN_EXPERIMENTAL(non_classe) == False) def test_IN_PRIVATE(self): tens = inet_atol("10.20.30.40") self.assert_(IN_PRIVATE(tens) == True) seventeens = inet_atol("172.16.254.3") self.assert_(IN_PRIVATE(seventeens) == True) nineteens = inet_atol("192.168.123.45") self.assert_(IN_PRIVATE(nineteens) == True) umpteens = inet_atol("192.0.2.1") self.assert_(IN_PRIVATE(umpteens) == False) loopback = inet_atol("127.0.0.1") self.assert_(IN_PRIVATE(loopback) == False) if __name__ == '__main__': unittest.main() if __name__ == '__main__': unittest.main() pcs-0.6/tests/etherping.out0000664000175000017500000000224011255512624015643 0ustar andreasandreas¡²ÃÔÿÿC~ )æbbÛ::w “DúbETˆ“@å@À¨e¦©å<¡•´-C~ )Ž  !"#$%&'()*+,-./01234567C ›ìff “DúbÛ::wET·@ëò©å<¡À¨e¦´-C~ )Ž  !"#$%&'()*+,-./01234567]ãåxC3bbÛ::w “DúbETˆ–@å=À¨e¦©å<¡Œ -C33  !"#$%&'()*+,-./01234567C€œÍff “DúbÛ::wET¸@ëò©å<¡À¨e¦” -C33  !"#$%&'()*+,-./01234567’ˆ½C€4 bbÛ::w “DúbETˆ™@å:À¨e¦©å<¡‹-C€3¾  !"#$%&'()*+,-./01234567C°µff “DúbÛ::wET¹@ëò©å<¡À¨e¦“-C€3¾  !"#$%&'()*+,-./01234567ÉPMâC4˜bbÛ::w “DúbETˆ@å6À¨e¦©å<¡Šò-C4I  !"#$%&'()*+,-./01234567C‚P|ff “DúbÛ::wETº@ëò©å<¡À¨e¦’ò-C4I  !"#$%&'()*+,-./01234567Ï&)ËC‚5%bbÛ::w “DúbETˆ¡@å2À¨e¦©å<¡Š`-C‚4Ù  !"#$%&'()*+,-./01234567Cƒ©–ff “DúbÛ::wET»@ëò©å<¡À¨e¦’`-C‚4Ù  !"#$%&'()*+,-./01234567çupcs-0.6/tests/loopping6.out0000664000175000017500000000117011255512624015574 0ustar andreasandreas¡²ÃÔÜCà¹k <<`:@€ì&Cà¹j³Cà¹kG<<`:@ë&Cà¹j³Càºk<<`:@€ì Càºj·CàºkA<<`:@ë Càºj·Cà»k<<`:@€ìCà»j¹Cà»kQ<<`:@ëCà»j¹Cà¼k<<`:@€ì"Cà¼j±Cà¼kA<<`:@ë"Cà¼j±pcs-0.6/tests/hexdumper.py0000664000175000017500000000171511255512624015506 0ustar andreasandreas# This hack by: Raymond Hettinger class hexdumper: """Given a byte array, turn it into a string. hex bytes to stdout.""" def __init__(self): self.FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' \ for x in range(256)]) # pretty dumping hate machine. def dump(self, src, length=8): result=[] for i in xrange(0, len(src), length): s = src[i:i+length] hexa = ' '.join(["%02X"%ord(x) for x in s]) printable = s.translate(self.FILTER) result.append("%04X %-*s %s\n" % \ (i, length*3, hexa, printable)) return ''.join(result) # dump in a way which can be embedded in a python string. def dump2(self, src, length=8): result=[] for i in xrange(0, len(src), length): s = src[i:i+length] hexa = ''.join(["\\x%02X"%ord(x) for x in s]) result.append("\"%-*s\"" % (length*3, hexa)) if i + length < len(src): result.append(" \\") result.append("\n") return ''.join(result) pcs-0.6/tests/ipv6test.py0000664000175000017500000001420311255512624015265 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ipv6test.py,v 1.4 2006/08/01 13:35:58 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on the IPv6 packet. # That is to say it first encodes a packet, then decodes it and makes # sure that the data matches. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import PcapConnector from pcs.packets.ipv6 import * from socket import AF_INET6, inet_pton class ip6TestCase(unittest.TestCase): def test_ipv6(self): # create one packet, copy its bytes, then compare their fields ip = ipv6() assert (ip != None) ip.traffic_class = 1 ip.flow = 0 ip.length = 64 ip.next_header = 6 ip.hop = 64 ip.src = inet_pton(AF_INET6, "::1") ip.dst = inet_pton(AF_INET6, "::1") # Create a packet to compare against ipnew = ipv6() ipnew.decode(ip.bytes) self.assertEqual(ip.bytes, ipnew.bytes, "bytes not equal") for field in ip._fieldnames: self.assertEqual(getattr(ip, field), getattr(ipnew, field), ("%s not equal" % field)) def test_ipv6_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = PcapConnector("loopping6.out") packet = file.read() ip = ipv6(packet[file.dloff:len(packet)]) assert (ip != None) self.assertEqual(ip.version, 6, "version not equal %d" % ip.version) self.assertEqual(ip.traffic_class, 0, "traffic_class not equal %d" % ip.traffic_class) self.assertEqual(ip.flow, 0, "flow not equal %d" % ip.flow) self.assertEqual(ip.length, 16, "length not equal %d" % ip.length) self.assertEqual(ip.next_header, 58, "next_header not equal %d" % ip.next_header) self.assertEqual(ip.hop, 64, "hop not equal %d" % ip.hop) self.assertEqual(ip.src, inet_pton(AF_INET6, "::1"), "src not equal %s" % ip.src) self.assertEqual(ip.dst, inet_pton(AF_INET6, "::1"), "dst not equal %s" % ip.dst) def test_ipv6_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("loopping6.out") packet = file.read() ip1 = ipv6(packet[file.dloff:len(packet)]) ip2 = ipv6(packet[file.dloff:len(packet)]) assert (ip1 != None) assert (ip2 != None) self.assertEqual(ip1, ip2, "packets should be equal but are not") ip1.dst = inet_pton(AF_INET6, "2001:ffff::1"); self.assertNotEqual(ip1, ip2, "packets compare equal but should not") def test_ipv6_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("loopping6.out") packet = file.read() ip = ipv6(packet[file.dloff:len(packet)]) assert (ip != None) test_string = "version 6\ntraffic_class 0\nflow 0\nlength 16\nnext_header 58\nhop 64\nsrc ::1\ndst ::1\n" string = ip.__str__() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) def test_ipv6_println(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("loopping6.out") packet = file.read() ip = ipv6(packet[file.dloff:len(packet)]) assert (ip != None) test_string = "" string = ip.println() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) if __name__ == '__main__': unittest.main() pcs-0.6/tests/wwwtcp.out0000664000175000017500000002636011255512625015223 0ustar andreasandreasÔò¡Ü¸ ]FwNN 2{œò1Ø|E@H±@@Õ‘ Sу$žÑ®PP‡ˆÇ°ÿÿ;¿´ 2€¸ ]F†³NNò1Ø| 2{œE@{@6­,у$ž SPÑ®²¶°P‡ˆÈ°ÿÿpt´ x ™È2€¸ ]FسBB 2{œò1Ø|E4H²@@Õœ Sу$žÑ®PP‡ˆÈ²¶±€ÿÿ°? 2€x ™È¸ ]F¿´ÑÑ 2{œò1Ø|EÃH³@@Õ Sу$žÑ®PP‡ˆÈ²¶±€ÿÿõ 2€x ™ÈGET / HTTP/1.1 User-Agent: curl/7.16.1 (i386-apple-darwin8.9.1) libcurl/7.16.1 OpenSSL/0.9.8e zlib/1.2.3 Host: www.yahoo.com Accept: */* ¸ ]FhRÜêò1Ø| 2{œEÜ|!@6¦…у$ž SPÑ®²¶±P‡‰W€‚ÙÎ x š12€HTTP/1.1 200 OK Date: Wed, 30 May 2007 05:25:17 GMT P3P: policyref="http://p3p.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE GOV" Cache-Control: private Vary: User-Agent Last-Modified: Wed, 30 May 2007 05:15:13 GMT Accept-Ranges: bytes Content-Length: 9463 Connection: close Content-Type: text/html; charset=utf-8 Yahoo!
Yahoo!
My Yahoo!
¸ ]FcSBB 2{œò1Ø|E4Hµ@@Õ™ Sу$žÑ®PP‡‰W²¶©€ÿÿžO 2€x š1¸ ]F”SÜêò1Ø| 2{œEÜ|$@6¦‚у$ž SPÑ®²¶©P‡‰W€‚N  x š12€le cellpadding="2" cellspacing="0" border="0" bgcolor="#DEE6E9">
My Mail
Why miss out?
To see all the new Yahoo! home page has to offer, please upgrade to a more recent browser.

Supported browsers include:
Internet Explorer 7 optimized by Yahoo!
Firefox 2.0
Safari 2.0
Opera 8.5
360°
Answers
Autos
Entertainment
Finance
GamesGeocities
Groups
Health
Horoscopes
HotJobs
Kids
Local
Maps
Messenger
Movies
Music
News
Personals
Photos
Real Estate
Shopping
Sports
Tech
Travel
TV
Weather
Yellow Pages
Y! International
Advertise with us | Search Marketing | Help | Privacy Policy | Terms of Service | Suggest a site | Yahoo! Telemundo | Yahoo! TV Ads

Copyright © 2007 Yahoo! Inc. All rights reserved. Copyright/IP Policy | Company Info | Jobs
¸ ]F¹íBB 2{œò1Ø|E4H·@@Õ— Sу$žÑ®PP‡‰W²¶-s€ô”  2€x šš¸ ]FÇHBB 2{œò1Ø|E4H¸@@Õ– Sу$žÑ®PP‡‰W²¶-s€ÿÿˆ 2€x šš¸ ]F$J BB 2{œò1Ø|E4H¹@@Õ• Sу$žÑ®PP‡‰W²¶-s€ÿÿˆ 2€x šš¸ ]Fšõ BBò1Ø| 2{œE4~è@6©fу$ž SPÑ®²¶-sP‡‰X€‚ x ›ž2€pcs-0.6/tests/udpv4test.py0000664000175000017500000001413711255512624015451 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: udpv4test.py,v 1.2 2005/11/11 00:22:07 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on an UDPv4 packet. That # is to say it first encodes a packet, then decodes is and makes sure # that the data matches. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.udp import * #from pcs.packets.udpv4 import * class udpTestCase(unittest.TestCase): def test_udpv4(self): # create one packet, copy its bytes, then compare their fields packet = udp() assert (packet != None) packet.sport = 67 packet.dport = 68 packet.length = 64 packet.checksum = 0 # Create a packet to compare against new_packet = udp() new_packet.decode(packet.bytes) self.assertEqual(packet.bytes, new_packet.bytes, "bytes not equal") for field in packet._fieldnames: self.assertEqual(getattr(packet, field), getattr(new_packet, field), ("%s not equal" % field)) def test_udpv4_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() packet = packet.data.data assert (packet != None) self.assertEqual(packet.sport, 50942, "sport not equal exptected: %d got: %d " % (50942, packet.sport)) self.assertEqual(packet.dport, 53, "dport not equal exptected: %d got: %d " % (53, packet.dport)) self.assertEqual(packet.length, 62, "length not equal exptected: %d got: %d " % (62, packet.length)) self.assertEqual(packet.checksum, 46791, "checksum not equal exptected: %d got: %d " % (46791, packet.checksum)) def test_udpv4_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) packet1 = udp(ip.data.bytes) packet2 = udp(ip.data.bytes) assert (packet1 != None) assert (packet2 != None) self.assertEqual(packet1, packet2, "packets should be equal but are not") packet1.dport = 0xffff self.assertNotEqual(packet1, packet2, "packets compare equal but should not\ngot %sexpect %s" % (packet1, packet2)) def test_udpv4_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) test_string = "UDP\nsport 50942\ndport 53\nlength 62\nchecksum 46791\n" packet = ip.data string = packet.__str__() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) def test_udpv4_raw(self): # Create a packet for raw injection and verify it meets criteria. from pcs import inet_atol from pcs.packets.payload import payload c = ethernet(src="\x01\x02\x03\x04\x05\x06", \ dst="\xff\xff\xff\xff\xff\xff") / \ ipv4(src=inet_atol("192.168.123.17"), \ dst=inet_atol("192.0.2.2"), id=5235) / \ udp(sport=67, dport=68) / \ payload("foobar\n") c.calc_lengths() c.calc_checksums() c.encode() expected = \ "\xFF\xFF\xFF\xFF\xFF\xFF\x01\x02" \ "\x03\x04\x05\x06\x08\x00\x45\x00" \ "\x00\x23\x14\x73\x00\x00\x40\x11" \ "\x68\x9B\xC0\xA8\x7B\x11\xC0\x00" \ "\x02\x02\x00\x43\x00\x44\x00\x0F" \ "\xC0\x48\x66\x6F\x6F\x62\x61\x72" \ "\x0A" gotttted = c.bytes self.assertEqual(expected, gotttted, "test raw encoding") if __name__ == '__main__': unittest.main() pcs-0.6/tests/dnstest.py0000664000175000017500000001553411255512624015175 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: dnstest.py,v 1.1 2006/09/01 05:24:04 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on the DNS packet. # That is to say it first encodes a packet, then decodes is and makes # sure that the data matches. import unittest import sys from hexdumper import hexdumper if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs.packets.dns import * from pcs.packets.ipv4 import ipv4 from pcs.packets.udpv4 import udpv4 import pcs class dnsTestCase(unittest.TestCase): def test_dns_header(self): # create one header, copy its bytes, then compare their fields dns = dnsheader() assert (dns != None) dns.id = 1 dns.query = 0 dns.opcode = 0 dns.aa = 0 dns.tc = 0 dns.rd = 1 dns.ra = 0 dns.z = 0 dns.rcode = 0 dns.qdcount = 1 dns.ancount = 0 dns.nscount = 0 dns.arcount = 0 # Create a packet to compare against dnsnew = dnsheader() dnsnew.decode(dns.bytes) self.assertEqual(dns.bytes, dnsnew.bytes, "bytes not equal") for field in dns._fieldnames: self.assertEqual(getattr(dns, field), getattr(dnsnew, field), ("%s not equal" % field)) def test_dns_query(self): # create one query, copy its bytes, then compare their fields dns = dnsquery() assert (dns != None) # XXX This field doesn't exist. Normally how the dns classes are # used is that labels go in front -- the code isn't yet smart # enough to encode labels at this level. dns.name = "neville-neil.com" dns.type = 1 dns.query_class = 1 dnsnew = dnsquery() assert (dnsnew != None) dnsnew.decode(dns.bytes) self.assertEqual(dns.type, dnsnew.type, "type not equal") self.assertEqual(dns.query_class, dnsnew.query_class, "class not equal") def test_dns_rr(self): # create one resource record, copy its bytes, then compare their fields dns = dnsrr() assert (dns != None) # XXX 'name' should really be a sequence of labels or pointers, # see RFC 1035, we just use a single string for now as implementing # the name compression is troublesome. # Both 'name' and 'rdata' encode as their entire field width. Of # course we have a variable field with, which the PCS reflection # in python doesn't grok. dns.name = "neville-neil.com" dns.type = 1 dns.query_class = 1 dns.ttl = 32 dns.rdata = "ns.meer.net" # XXX this DOESN'T copy the LengthValue fields, why? #dnsnew = dnsrr() #dnsnew.decode(dns.bytes) dnsnew = dnsrr(dns.bytes) assert (dnsnew != None) #print #print "'%s'" % dns.name.value.value #print "'%s'" % dnsnew.name.value.value #print "'%s'" % dns.rdata.value.value #print "'%s'" % dnsnew.rdata.value.value # XXX accessor for dns.name produces field, not string. #self.assertEqual(dns.name, dnsnew.name, "name not equal") self.assertEqual(dns.name.value.value, dnsnew.name.value.value, "name not equal") self.assertEqual(dns.type, dnsnew.type, "type not equal") self.assertEqual(dns.query_class, dnsnew.query_class, "class not equal") self.assertEqual(dns.ttl, dnsnew.ttl, "ttl not equal") #self.assertEqual(dns.rdata, dnsnew.rdata, "rdata not equal") #self.assertEqual(dns.rdata.value.value, dnsnew.rdata.value.value, "rdata not equal") def test_dns_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) udp = ip.data dns = udp.data def test_dns_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) udp1 = udpv4(ip.data.bytes) udp2 = udpv4(ip.data.bytes) assert (udp1 != None) assert (udp2 != None) self.assertEqual(udp1, udp2, "packets should be equal but are not") udp1.dport = 0xffff self.assertNotEqual(udp1, udp2, "packets compare equal but should not\ngot %sexpect %s" % (udp1, udp2)) def test_dns_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = pcs.PcapConnector("dns.out") packet = file.readpkt() ip = packet.data assert (ip != None) test_string = "UDP\nsport 50942\ndport 53\nlength 62\nchecksum 46791\n" udpv4 = ip.data string = udpv4.__str__() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) if __name__ == '__main__': unittest.main() pcs-0.6/tests/divtest.py0000664000175000017500000000774411255512624015177 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Test the Scapy-style chain construction syntax. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs from pcs import * import pcs.packets.ethernet as ethernet import pcs.packets.ipv4 as ipv4 import pcs.packets.udpv4 as udpv4 import pcs.packets.dhcpv4 as dhcpv4 class divTestCase(unittest.TestCase): def test_div(self): """Test the Scapy-style chain construction syntax.""" # Create a bunch of individual packets. a = ethernet.ethernet() b = ipv4.ipv4() c = udpv4.udpv4(sport=1234) d = dhcpv4.dhcpv4() # Pack them into chains, assert that their properties still hold. x = a / b self.assertEqual(len(x.packets), 2, "x does not have 2 packets") self.assertEqual(x.packets[0].type, 0x0800, \ "x[0].type is not ETHERTYPE_IP") # XXX The link in the existing chain must be broken for these # invariants to hold; the semantics of chains have changed therefore # these need to be updated. #y = b / c #self.assertEqual(len(y.packets), 2, "y does not have 2 packets") #self.assertEqual(y.packets[0].protocol, 17, \ # "y.packets[0].protocol is not UDP") #z = c / d #self.assertEqual(len(z.packets), 2, "z does not have 2 packets") #self.assertEqual(z.packets[0].sport, 1234, "z.packets[0].sport is not 1234") #self.assertEqual(z.packets[0].dport, 67, "z.packets[0].dport is not 67") # All together now. alpha = ethernet.ethernet() / ipv4.ipv4() / udpv4.udpv4(sport=1234) / \ dhcpv4.dhcpv4() self.assertEqual(len(alpha.packets), 4, "alpha does not have 4 packets") self.assertEqual(alpha.packets[0].type, 0x0800, \ "alpha.packets[0].type is not ETHERTYPE_IP") self.assertEqual(alpha.packets[1].protocol, 17, \ "alpha.packets[1].protocol is not UDP") self.assertEqual(alpha.packets[2].sport, 1234, \ "alpha.packets[2].sport is not 1234") self.assertEqual(alpha.packets[2].dport, 67, \ "alpha.packets[2].dport is not 67") if __name__ == '__main__': unittest.main() pcs-0.6/tests/igmpv3test.py0000664000175000017500000001120311255512624015603 0ustar andreasandreas#!/usr/bin/env python import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues from hexdumper import hexdumper from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv3 import * from pcs import * class igmpv3TestCase(unittest.TestCase): def test_igmpv3_encode(self): # create one packet, copy its bytes, then compare their fields. c = igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) / igmpv3.report() rep = c.packets[1] # An ASM/SSM leave. rec0 = GroupRecordField("rec0") rec0.type.value = IGMP_CHANGE_TO_INCLUDE rec0.group.value = inet_atol("239.0.1.2") rep.records.append(rec0) # An SSM join. rec1 = GroupRecordField("rec1") rec1.type.value = IGMP_CHANGE_TO_INCLUDE rec1.group.value = inet_atol("239.3.2.1") rec1.sources.append(pcs.Field("", 32, default = inet_atol("192.0.2.1"))) rec1.nsources.value = len(rec1.sources) rep.records.append(rec1) # An ASM join. rec2 = GroupRecordField("rec2") rec2.type.value = IGMP_CHANGE_TO_EXCLUDE rec2.group.value = inet_atol("224.111.222.111") rep.records.append(rec2) # An ASM filter change. # XXX I can't get auxiliary data embedding to work reliably, # this seems to be because the syntactic sugar for OptionListField # makes it difficult to retrieve the size of the embedded fields. rec3 = GroupRecordField("rec3") rec3.type.value = IGMP_BLOCK_OLD_SOURCES rec3.group.value = inet_atol("225.4.3.2") rec3.sources.append(pcs.Field("", 32, default = inet_atol("192.0.2.99"))) rec3.nsources.value = len(rec3.sources) rep.records.append(rec3) rep.nrecords = len(rep.records) c.calc_checksums() c.encode() #hd = hexdumper() #print hd.dump2(c.bytes) expected = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \ "\x03\x00\x00\x00\xEF\x00\x01\x02" \ "\x03\x00\x00\x01\xEF\x03\x02\x01" \ "\xC0\x00\x02\x01\x04\x00\x00\x00" \ "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \ "\xE1\x04\x03\x02\xC0\x00\x02\x63" #print hd.dump2(expected) gotttted = c.bytes self.assertEqual(expected, gotttted, "test encoding") def test_igmpv3_decode(self): # Try decoding the same packet as above, see what we get. input = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \ "\x03\x00\x00\x00\xEF\x00\x01\x02" \ "\x03\x00\x00\x01\xEF\x03\x02\x01" \ "\xC0\x00\x02\x01\x04\x00\x00\x00" \ "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \ "\xE1\x04\x03\x02\xC0\x00\x02\x63" igh = igmp(input) self.assertEqual(input, igh.chain().bytes, "test decoding") def test_igmpv3_encode_kv(self): # Create reports using the new syntax. #c = igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) / \ c = igmp() / \ igmpv3.report(records=[GroupRecordField("", \ group=inet_atol("239.0.1.2"), \ type=IGMP_CHANGE_TO_INCLUDE), GroupRecordField("", \ group=inet_atol("239.3.2.1"), \ type=IGMP_CHANGE_TO_INCLUDE, \ sources=[inet_atol("192.0.2.1")]), \ GroupRecordField("", \ group=inet_atol("224.111.222.111"), \ type=IGMP_CHANGE_TO_EXCLUDE), \ GroupRecordField("", \ group=inet_atol("225.4.3.2"), \ type=IGMP_BLOCK_OLD_SOURCES, \ sources=[inet_atol("192.0.2.99")])]) c.calc_lengths() c.calc_checksums() c.encode() #hd = hexdumper() #print hd.dump2(c.bytes) expected = "\x22\x00\xC5\xA5\x00\x00\x00\x04" \ "\x03\x00\x00\x00\xEF\x00\x01\x02" \ "\x03\x00\x00\x01\xEF\x03\x02\x01" \ "\xC0\x00\x02\x01\x04\x00\x00\x00" \ "\xE0\x6F\xDE\x6F\x06\x00\x00\x01" \ "\xE1\x04\x03\x02\xC0\x00\x02\x63" #print hd.dump2(expected) gotttted = c.bytes self.assertEqual(expected, gotttted, "test encoding") if __name__ == '__main__': unittest.main() pcs-0.6/tests/copytest.py0000664000175000017500000004172611255512624015365 0ustar andreasandreas# Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id$ # # Author: Bruce M. Simpson # # Description: Test shallow and deep copies of PCS objects. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from copy import copy from copy import deepcopy import pcs from pcs import * from pcs.packets.ethernet import ether_atob class copyTestCase(unittest.TestCase): def test_copy_field(self): """Test shallow copy of Field. Field is not immutable and contains only data types, so deep and shallow copies are identical.""" addr1 = inet_atol("192.0.2.1") addr2 = inet_atol("192.0.2.2") f1 = pcs.Field("f1", 32, default=addr1) self.assert_(isinstance(f1, pcs.Field)) self.assertEqual(f1.value, addr1, "f1's value not set by __init__!") f1.value = addr2 self.assertEqual(f1.value, addr2, "f1's value not set by assignment!") f2 = copy(f1) # should have same name and type self.assertEqual(f2.packet, None, "f2.packet is not None!") self.assert_(isinstance(f2, pcs.Field)) self.assertEqual(f2.name, "f1", "f2's name not set by copy()!") self.assertEqual(f2.value, addr2, "f2's value not set by copy()!") f2.value = addr1 self.assertEqual(f2.value, addr1, "f2's value not set by assignment!") self.assert_(f1.value != f2.value) def test_copy_lengthvaluefield(self): """Test shallow copy of LengthValueField. It contains two other Fields, so a shallow copy should copy only those members.""" addr1 = inet_atol("192.0.2.1") lf1 = pcs.Field("", 8) vf1 = pcs.Field("", 32) lvf1 = LengthValueField("lvf1", lf1, vf1) self.assert_(isinstance(lvf1, pcs.LengthValueField)) self.assert_(isinstance(lvf1.length, pcs.Field)) self.assert_(isinstance(lvf1.value, pcs.Field)) self.assert_(id(lf1) == id(lvf1.length)) self.assert_(id(vf1) == id(lvf1.value)) vf1.value = addr1 self.assertEqual(lvf1.value.value, addr1, \ "lvf1's value-field value not set by assignment!") lvf2 = copy(lvf1) self.assertEqual(lvf2.packet, None, "lvf2.packet is not None!") self.assert_(isinstance(lvf2, pcs.LengthValueField)) self.assert_(isinstance(lvf2.length, pcs.Field)) self.assert_(isinstance(lvf2.value, pcs.Field)) # Must be a shallow copy self.assert_(id(lf1) == id(lvf2.length)) self.assert_(id(vf1) == id(lvf2.value)) self.assertEqual(lvf2.name, "lvf1", "lvf2's name not set by copy()!") # Paranoia self.assertEqual(lvf2.value.value, inet_atol("192.0.2.1"), \ "lvf2's value-field value differs!") def test_copy_optionlistfield(self): """Test shallow copy of OptionListField.""" of1 = OptionListField("") self.assert_(isinstance(of1, pcs.OptionListField)) f1 = Field("", 8) self.assert_(isinstance(f1, pcs.Field)) f1.value = 123 of1.append(f1) self.assert_(len(of1), 1) self.assert_(isinstance(of1._options[0], pcs.Field)) self.assert_(id(of1._options[0]) == id(f1)) of2 = copy(of1) self.assert_(isinstance(of2, pcs.OptionListField)) self.assert_(id(of1) != id(of2)) self.assertEqual(of2._options[0].value, 123, "of2's first option's value-field value differs!") def test_copy_typevaluefield(self): """Test shallow copy of TypeValueField.""" addr1 = inet_atol("192.0.2.1") tf1 = pcs.Field("", 8) vf1 = pcs.Field("", 32) tvf1 = TypeValueField("tvf1", tf1, vf1) self.assert_(isinstance(tvf1, pcs.TypeValueField)) self.assert_(isinstance(tvf1.type, pcs.Field)) self.assert_(isinstance(tvf1.value, pcs.Field)) self.assert_(id(tf1) == id(tvf1.type)) self.assert_(id(vf1) == id(tvf1.value)) tvf1.value.value = addr1 self.assertEqual(tvf1.value.value, addr1, \ "tvf1's value-field value not set by assignment!") tvf2 = copy(tvf1) self.assert_(id(tvf1) != id(tvf2)) self.assertEqual(tvf2.packet, None, "tvf2.packet is not None!") self.assert_(isinstance(tvf2, pcs.TypeValueField)) self.assert_(isinstance(tvf2.type, pcs.Field)) self.assert_(isinstance(tvf2.value, pcs.Field)) # Must be a shallow copy self.assert_(id(tf1) == id(tvf2.type)) self.assert_(id(vf1) == id(tvf2.value)) self.assertEqual(tvf2.name, "tvf1", \ "tvf2's name not set by copy()!") # Paranoia self.assertEqual(tvf2.value.value, inet_atol("192.0.2.1"), \ "tvf2's value-field value differs!") def test_copy_typelengthvaluefield(self): """Test shallow copy of TypeLengthValueField. It contains three other Fields, so a deep copy should copy everything.""" addr1 = inet_atol("192.0.2.1") tf1 = pcs.Field("", 8) lf1 = pcs.Field("", 8) vf1 = pcs.Field("", 32) tlvf1 = TypeLengthValueField("tlvf1", tf1, lf1, vf1) self.assert_(isinstance(tlvf1, pcs.TypeLengthValueField)) self.assert_(isinstance(tlvf1.type, pcs.Field)) self.assert_(isinstance(tlvf1.length, pcs.Field)) self.assert_(isinstance(tlvf1.value, pcs.Field)) self.assert_(id(tf1) == id(tlvf1.type)) self.assert_(id(lf1) == id(tlvf1.length)) self.assert_(id(vf1) == id(tlvf1.value)) tlvf1.type.value = 123 tlvf1.length.value = 4 tlvf1.value.value = addr1 self.assertEqual(tlvf1.value.value, addr1, \ "tlvf1's value-field value not set by assignment!") addr2 = ether_atob("01:02:03:04:05:06") tlvf2 = copy(tlvf1) self.assert_(id(tlvf1) != id(tlvf2)) self.assertEqual(tlvf2.packet, None, "tlvf2.packet is not None!") self.assert_(isinstance(tlvf2, pcs.TypeLengthValueField)) self.assert_(isinstance(tlvf2.type, pcs.Field)) self.assert_(isinstance(tlvf2.length, pcs.Field)) self.assert_(isinstance(tlvf2.value, pcs.Field)) # Must be a shallow copy self.assert_(id(tf1) == id(tlvf2.type)) self.assert_(id(lf1) == id(tlvf2.length)) self.assert_(id(vf1) == id(tlvf2.value)) self.assertEqual(tlvf2.name, "tlvf1", \ "tlvf2's name not set by deepcopy()!") # Paranoia self.assertEqual(tlvf2.type.value, 123, \ "tlvf2's value-field value differs after deepcopy!") self.assertEqual(tlvf2.length.value, 4, \ "tlvf2's value-field value differs after deepcopy!") self.assertEqual(tlvf2.value.value, inet_atol("192.0.2.1"), \ "tlvf2's value-field value differs after deepcopy!") def test_copy_packet(self): """A copy of a Packet is always deep.""" self.test_deepcopy_packet() def test_copy_chain(self): """A copy of a Chain is always deep.""" self.test_deepcopy_chain() def test_deepcopy_field(self): """A copy of a Field is always deep.""" self.test_copy_field() def test_deepcopy_optionlistfield(self): """Test deep copy of OptionListField.""" of1 = OptionListField("") self.assert_(isinstance(of1, pcs.OptionListField)) f1 = Field("", 8) self.assert_(isinstance(f1, pcs.Field)) f1.value = 123 of1.append(f1) self.assert_(len(of1), 1) self.assert_(isinstance(of1._options[0], pcs.Field)) self.assert_(id(of1._options[0]) == id(f1)) of2 = deepcopy(of1) self.assert_(isinstance(of2, pcs.OptionListField)) self.assert_(id(of1) != id(of2)) self.assert_(isinstance(of2._options[0], pcs.Field)) self.assert_(id(of1._options[0]) != id(of2._options[0])) def test_deepcopy_lengthvaluefield(self): """Test deep copy of LengthValueField. It contains two other Fields, so a deep copy should copy everything.""" addr1 = inet_atol("192.0.2.1") lf1 = pcs.Field("", 8) vf1 = pcs.Field("", 32) lvf1 = LengthValueField("lvf1", lf1, vf1) self.assert_(isinstance(lvf1, pcs.LengthValueField)) self.assert_(isinstance(lvf1.length, pcs.Field)) self.assert_(isinstance(lvf1.value, pcs.Field)) self.assert_(id(lf1) == id(lvf1.length)) self.assert_(id(vf1) == id(lvf1.value)) lvf1.value.value = addr1 self.assertEqual(lvf1.value.value, addr1, \ "lvf1's value-field value not set by assignment!") addr2 = ether_atob("01:02:03:04:05:06") lvf2 = deepcopy(lvf1) self.assert_(id(lvf1) != id(lvf2)) self.assertEqual(lvf2.packet, None, "lvf2.packet is not None!") self.assert_(isinstance(lvf2, pcs.LengthValueField)) self.assert_(isinstance(lvf2.length, pcs.Field)) self.assert_(isinstance(lvf2.value, pcs.Field)) # Must be a deep copy self.assert_(id(lf1) != id(lvf2.length)) self.assert_(id(vf1) != id(lvf2.value)) self.assertEqual(lvf2.name, "lvf1", \ "lvf2's name not set by deepcopy()!") # Paranoia self.assertEqual(lvf2.value.value, inet_atol("192.0.2.1"), \ "lvf2's value-field value differs after deepcopy!") lvf1.value.value = inet_atol("192.0.2.2") self.assertEqual(lvf2.value.value, inet_atol("192.0.2.1"), \ "lvf2's value-field value was changed by assignment to lvf1!") lvf2.length.value = len(addr2) lvf2.value.value = addr2 self.assertNotEqual(lvf1.length.value, lvf2.length.value, "lvf2's length-field value does not differ after assignment!") def test_deepcopy_typevaluefield(self): """Test deep copy of TypeValueField. It contains two other Fields, so a deep copy should copy everything.""" addr1 = inet_atol("192.0.2.1") tf1 = pcs.Field("", 8) vf1 = pcs.Field("", 32) tvf1 = TypeValueField("tvf1", tf1, vf1) self.assert_(isinstance(tvf1, pcs.TypeValueField)) self.assert_(isinstance(tvf1.type, pcs.Field)) self.assert_(isinstance(tvf1.value, pcs.Field)) self.assert_(id(tf1) == id(tvf1.type)) self.assert_(id(vf1) == id(tvf1.value)) tvf1.value.value = addr1 self.assertEqual(tvf1.value.value, addr1, \ "tvf1's value-field value not set by assignment!") addr2 = ether_atob("01:02:03:04:05:06") tvf2 = deepcopy(tvf1) self.assert_(id(tvf1) != id(tvf2)) self.assertEqual(tvf2.packet, None, "tvf2.packet is not None!") self.assert_(isinstance(tvf2, pcs.TypeValueField)) self.assert_(isinstance(tvf2.type, pcs.Field)) self.assert_(isinstance(tvf2.value, pcs.Field)) # Must be a deep copy self.assert_(id(tf1) != id(tvf2.type)) self.assert_(id(vf1) != id(tvf2.value)) self.assertEqual(tvf2.name, "tvf1", \ "tvf2's name not set by deepcopy()!") # Paranoia self.assertEqual(tvf2.value.value, inet_atol("192.0.2.1"), \ "tvf2's value-field value differs after deepcopy!") tvf1.value.value = inet_atol("192.0.2.2") self.assertEqual(tvf2.value.value, inet_atol("192.0.2.1"), \ "tvf2's value-field value was changed by assignment to tvf1!") tvf2.type.value = 123 tvf2.value.value = addr2 self.assertNotEqual(tvf1.type.value, tvf2.type.value, "lvf2's type-field value does not differ after assignment!") def test_deepcopy_typelengthvaluefield(self): """Test deep copy of TypeLengthValueField. It contains three other Fields, so a deep copy should copy everything.""" addr1 = inet_atol("192.0.2.1") tf1 = pcs.Field("", 8) lf1 = pcs.Field("", 8) vf1 = pcs.Field("", 32) tlvf1 = TypeLengthValueField("tlvf1", tf1, lf1, vf1) self.assert_(isinstance(tlvf1, pcs.TypeLengthValueField)) self.assert_(isinstance(tlvf1.type, pcs.Field)) self.assert_(isinstance(tlvf1.length, pcs.Field)) self.assert_(isinstance(tlvf1.value, pcs.Field)) self.assert_(id(tf1) == id(tlvf1.type)) self.assert_(id(lf1) == id(tlvf1.length)) self.assert_(id(vf1) == id(tlvf1.value)) tlvf1.value.value = addr1 self.assertEqual(tlvf1.value.value, addr1, \ "tlvf1's value-field value not set by assignment!") addr2 = ether_atob("01:02:03:04:05:06") tlvf2 = deepcopy(tlvf1) self.assert_(id(tlvf1) != id(tlvf2)) self.assertEqual(tlvf2.packet, None, "tlvf2.packet is not None!") self.assert_(isinstance(tlvf2, pcs.TypeLengthValueField)) self.assert_(isinstance(tlvf2.type, pcs.Field)) self.assert_(isinstance(tlvf2.length, pcs.Field)) self.assert_(isinstance(tlvf2.value, pcs.Field)) # Must be a deep copy self.assert_(id(tf1) != id(tlvf2.type)) self.assert_(id(lf1) != id(tlvf2.length)) self.assert_(id(vf1) != id(tlvf2.value)) self.assertEqual(tlvf2.name, "tlvf1", \ "tlvf2's name not set by deepcopy()!") # Paranoia self.assertEqual(tlvf2.value.value, inet_atol("192.0.2.1"), \ "tlvf2's value-field value differs after deepcopy!") tlvf1.value.value = inet_atol("192.0.2.2") self.assertEqual(tlvf2.value.value, inet_atol("192.0.2.1"), \ "tlvf2's value-field value was changed by assignment to tvf1!") tlvf2.type.value = 123 self.assertNotEqual(tlvf1.type.value, tlvf2.type.value, "tlvf2's type-field value does not differ after assignment!") tlvf2.length.value = len(addr2) self.assertNotEqual(tlvf1.length.value, tlvf2.length.value, "tlvf2's length-field value does not differ after assignment!") tlvf2.value.value = addr2 self.assertNotEqual(tlvf1.type.value, tlvf2.type.value, "tvf2's type-field value does not differ after assignment!") def test_deepcopy_packet(self): from pcs.packets.ipv4 import ipv4 p1 = ipv4(id=123) self.assert_(isinstance(p1, ipv4)) p2 = deepcopy(p1) self.assert_(isinstance(p2, ipv4)) self.assert_(id(p2) != id(p1)) self.assert_(id(p2._fieldnames['id']) != id(p1._fieldnames['id'])) self.assert_(p2.id == p1.id) p2.id = 456 self.assert_(id(p2._fieldnames['id']) != id(p1._fieldnames['id'])) self.assert_(p2.id != p1.id) # Copying a Packet DOES NOT copy its payload. self.assert_(p2.data == None) def test_deepcopy_chain(self): from pcs.packets.ipv4 import ipv4 c1 = Chain([ipv4()]) p1 = c1.packets[0] self.assert_(p1._head is c1) c2 = deepcopy(c1) self.assert_(c2 is not c1) p2 = c2.packets[0] self.assert_(p2 is not p1) self.assert_(p2._head is c2) self.assert_(id(p2) != id(p1)) self.assert_(id(p2._fieldnames['id']) != id(p1._fieldnames['id'])) pass if __name__ == '__main__': unittest.main() pcs-0.6/tests/sctptest.py0000664000175000017500000000606511255512624015361 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: A test for the SCTP protocol import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import PcapConnector from pcs.packets.ipv4 import * from pcs.packets.sctp import * class sctpTestCase(unittest.TestCase): def test_sctp(self): """Create one packet""" packet = common() assert(packet != None) packet.sport = 9999 packet.dport = 123 packet.tag = 10000 packet.checksum = 0 new_packet = common() new_packet.decode(packet.bytes) self.assertEqual(packet.bytes, new_packet.bytes, "bytes not equal") for field in packet._fieldnames: self.assertEqual(getattr(packet, field), getattr(new_packet, field), ("%s not equal" % field)) def test_sctp_read(self): """Read a packet from a pcap file.""" file = PcapConnector("sctp.pcap") packet = file.readpkt() sctp = packet.data.data assert (sctp != None) expected = "" got = sctp.println() self.assertEqual(expected, got, \ "strings are not equal \nexpected %s \ngot %s " % \ (expected, got)) if __name__ == '__main__': unittest.main() pcs-0.6/tests/icmpv4test.py0000664000175000017500000001412211255512624015603 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: icmpv4test.py,v 1.8 2006/09/05 07:30:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This module performs a self test on the IPv4 packet. # That is to say it first encodes a packet, then decodes it and makes # sure that the data matches. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues from pcs.packets.ethernet import ethernet from pcs.packets.ipv4 import * from pcs.packets.icmpv4 import * from pcs import * class icmpTestCase(unittest.TestCase): def test_icmpv4(self): # create one packet, copy its bytes, then compare their fields icmp = icmpv4() assert (icmp != None) icmp.type = 8 icmp.code = 0 # Create a packet to compare against icmpnew = icmpv4() icmpnew.decode(icmp.bytes) self.assertEqual(icmp.bytes, icmpnew.bytes, "bytes not equal") self.assertEqual(icmpnew.type, 8, "type not equal %d" % icmp.type) self.assertEqual(icmpnew.code, 0, "code not equal %d" % icmp.code) def test_icmpv4_read(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface.""" file = PcapConnector("loopping.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) icmp = ip.data self.assertEqual(icmp.type, 8, "type not equal to 8") self.assertEqual(icmp.code, 0, "code not equal to 0") def test_icmpv4_compare(self): """Test the underlying __compare__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("loopping.out") packet = file.read() ip1 = ipv4(packet[file.dloff:len(packet)]) ip2 = ipv4(packet[file.dloff:len(packet)]) assert (ip1 != None) assert (ip2 != None) icmp1 = ip1.data icmp2 = ip2.data self.assertEqual(icmp1, icmp2, "packets should be equal but are not") icmp1.code = 32 self.assertNotEqual(icmp1, icmp2, "packets compare equal but should not") def test_icmpv4_print(self): """This test reads from a pre-stored pcap file generated with tcpdump and ping on the loopback interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("loopping.out") packet = file.read() ip = ipv4(packet[file.dloff:len(packet)]) assert (ip != None) icmp = ip.data #test_string = "ICMPv4\ntype 8\ncode 0\nchecksum 60550\n" test_string = "ICMPv4 Echo Request\ntype 8\ncode 0\nchecksum 60550\n" string = icmp.__str__() self.assertEqual(string, test_string, "strings are not equal \nexpected %s \ngot %s " % (test_string, string)) def test_icmpv4_ping(self): import os uname = os.uname()[0] if uname == "FreeBSD": devname = "edsc0" elif uname == "Linux": devname = "lo" elif uname == "Darwin": devname = "en0" else: print "unknown host os %s" % uname return e = ethernet() e.type = 0x0800 e.src = "\x00\x00\x00\x00\x00\x00" e.dst = "\xff\xff\xff\xff\xff\xff" e.type = 0x0800 ip = ipv4() ip.version = 4 ip.hlen = 5 ip.tos = 0 ip.length = 28 ip.id = 1234 ip.flags = 0 ip.offset = 0 ip.ttl = 64 ip.protocol = IPPROTO_ICMP ip.src = inet_atol("127.0.0.1") ip.dst = inet_atol("127.0.0.1") icmp = icmpv4() icmp.type = 8 icmp.code = 0 icmp.cksum = 0 echo = icmpv4echo() echo.id = 37123 echo.sequence = 0 ip.len = len(ip.bytes) + len(icmp.bytes) + len(echo.bytes) packet = Chain([e, ip, icmp, echo]) packet.calc_checksums() packet.encode() input = PcapConnector(devname) input.setfilter("icmp") output = PcapConnector(devname) assert (ip != None) # XXX The use of IP triggers a bpf header format bug if used # with loopback device on FreeBSD, so we use edsc(4) there. n_out = output.write(packet.bytes, 42) assert (n_out == 42) packet_in = input.read() assert (n_out == len(packet_in)) if __name__ == '__main__': unittest.main() pcs-0.6/tests/maptest.py0000664000175000017500000000557011255512624015165 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. from pcs import PcapConnector from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.null import * import pcs.packets.ethernet_map class mapTestCase(unittest.TestCase): def test_map(self): # We're going to replace the higher layer protocol with the NULL # protocol. (Actually we're replacing it with Folger's Crystals.) """This test reads from a pre-stored pcap file generated with tcpdump and ping on an ethernet interface and tests the __str__ method to make sure the correct values are printed.""" file = PcapConnector("etherping.out") packet = file.readpkt() self.assertEqual(type(packet.data), ipv4) file.close # Replace the mapping of IPv4 ethernet_map.map[ethernet_map.ETHERTYPE_IP] = null file = PcapConnector("etherping.out") packet = file.readpkt() self.assertEqual(type(packet.data), null) file.close if __name__ == "__main__": unittest.main() pcs-0.6/tests/optiontest.py0000664000175000017500000000753011255512624015716 0ustar andreasandreas# Copyright (c) 2007, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id:$ # # Author: George V. Neville-Neil # # Description: A test of the option fields in PCS. import unittest import sys from hexdumper import hexdumper if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs from pcs.packets.tcp import * # # TODO: Rototile interface so that consumers do not need to # have knowledge of option structure, currently the option # code needs to be explicitly specified. # # Also this doesn't forcibly pad to 32 bits, nor does it check # that the length of all options wouldn't exceed 40. # class optionTestCase(unittest.TestCase): def test_tcp_with_options(self): """Assert that a TCP with options is correctly encoded.""" packet = tcp() nop = pcs.Field("nop", 8) mss = pcs.TypeLengthValueField("mss", pcs.Field("t", 8, default = 0x02), pcs.Field("l", 8), pcs.Field("v", 16)) end = pcs.Field("end", 8) nop.value = 1 mss.value.value = 1460 # Most common Internet MSS value. # Build a TCP option list which will be 32-bits aligned. packet.options.append(nop) packet.options.append(nop) packet.options.append(mss) packet.options.append(nop) packet.options.append(end) expected = "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x01\x01\x02\x04" \ "\x05\xb4\x01\x00" got = packet.bytes #packet.encode() #hd = hexdumper() #print hd.dump(expected) #print hd.dump(got) # XXX: Note well: just because you added an option list, # doesn't mean the TCP option length is correct. self.assertEqual(expected, got) def test_tcp_without_options(self): """Assert that a TCP without options does not get any additional fields appended to it on the wire.""" packet = tcp() expected = "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00\x00\x00\x00\x00" \ "\x00\x00\x00\x00" got = packet.bytes #packet.encode() #hd = hexdumper() #print hd.dump(expected) #print hd.dump(got) self.assertEqual(len(packet.options), 0) self.assertEqual(expected, got) if __name__ == '__main__': unittest.main() pcs-0.6/tests/chaintest.py0000664000175000017500000001042111255512624015461 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: chaintest.py,v 1.3 2006/06/27 14:45:43 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A test of the Chain class in PCS. import unittest import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs from pcs.packets.ethernet import ethernet from pcs.packets.ipv4 import ipv4 from pcs import * class chainTestCase(unittest.TestCase): def test_chain_compare(self): """Test the underlying __eq__ functionality of the packet. Two packets constructed from the same bytes should be equal and two that are not should not be equal.""" file = PcapConnector("loopping.out") packet = file.readpkt() # Create new packets don't just point to them ip1 = ipv4(packet.data.bytes) ip2 = ipv4(packet.data.bytes) assert (ip1 != None) assert (ip2 != None) ether1 = ethernet() ether1.src = "\x00\x00\x00\x00\x00\x01" ether1.dst = "\x00\x00\x00\x00\x00\x02" ether2 = ethernet() ether2.src = "\x00\x00\x00\x00\x00\x01" ether2.dst = "\x00\x00\x00\x00\x00\x02" chain1 = Chain([ether1, ip1]) chain2 = Chain([ether2, ip2]) self.assertEqual(chain1, chain2, "chains should be equal but are not") ip1.dst = 0 self.assertNotEqual(chain1, chain2, "chains compare equal but should not") def test_chain_read(self): """Test whether or not the chain method of the base class works.""" file = PcapConnector("loopping.out") packet = file.readpkt() chain = packet.chain() #test_string = "Localhost\ntype 2\n IPv4\nversion 4\nhlen 5\ntos 0\nlength 84\nid 59067\nflags 0\noffset 0\nttl 64\nprotocol 1\nchecksum 0\nsrc 127.0.0.1\ndst 127.0.0.1\noptions []\n ICMPv4\ntype 8\ncode 0\nchecksum 60550\n Payload\n\'\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\'()*+,-./01234567' " test_string = "Localhost\ntype 2\n IPv4\nversion 4\nhlen 5\ntos 0\nlength 84\nid 59067\nflags 0\noffset 0\nttl 64\nprotocol 1\nchecksum 0\nsrc 127.0.0.1\ndst 127.0.0.1\noptions []\n ICMPv4 Echo Request\ntype 8\ncode 0\nchecksum 60550\n ICMPv4 Echo\nid 23366\nsequence 0\n Payload\n\'B\\xf8s\\xad\\x00\\r\\x0e}\\x08\\t\\n\\x0b\\x0c\\r\\x0e\\x0f\\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f !\"#$%&\\\'()*+,-./01234567\' " string = chain.__str__() self.assertEqual(test_string, string, "strings not equal \ngot\n'%s'\nexpected\n'%s'" % (string, test_string)) if __name__ == '__main__': unittest.main() pcs-0.6/scripts/0000775000175000017500000000000011323556365013462 5ustar andreasandreaspcs-0.6/scripts/pcap_info.py0000664000175000017500000001740711255512624015775 0ustar andreasandreas#!/usr/bin/env python26 # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: Walk through an entire pcap dump file and give out # information along the lines of netstat(1) on FreeBSD. import cProfile import time import datetime from socket import inet_ntoa import sys if __name__ == '__main__': if "-l" in sys.argv: sys.path.insert(0, "../") # Look locally first sys.argv.remove("-l") # Needed because unittest has issues # with extra arguments. import pcs from pcs import PcapConnector from pcs.packets.udp import * from pcs.packets.tcp import * from pcs.packets.ipv4 import * from pcs.packets.icmpv4 import * from pcs.packets.ethernet import * from pcs.packets.arp import * def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-p", "--per-second", dest="ps", default=None, help="generate a graph of packets and bytes per second") parser.add_option("-m", "--per-millisecond", dest="ppm", default=None, help="generate a graph of packets and bytes per millisecond") parser.add_option("-u", "--per-microsecond", dest="ppu", default=None, help="generate a graph of packets and bytes per microsecond") (options, args) = parser.parse_args() # Files are specified as the remaining arguments. for dump_file in args: file = pcs.PcapConnector(dump_file) srcmap = {} packets_per = {} packets = 0 ip_cnt = 0 non_ip_cnt = 0 tcp_cnt = 0 udp_cnt = 0 icmp_cnt = 0 arp_cnt = 0 done = False while not done: try: packet = file.readpkt() except: done = True packets += 1 network = packet.data try: transport = network.data except: pass if type(network) == ipv4: ip_cnt += 1 ip = network else: non_ip_cnt += 1 if type(packet) == arp: arp_cnt += 1 if type(transport) == icmpv4: icmp_cnt += 1 if type(transport) == udp: udp_cnt += 1 if type(transport) == tcp: tcp_cnt += 1 try: srcmap[ip.src] += 1 except KeyError: srcmap[ip.src] = 1 if options.ps is not None: second = int(packet.timestamp) try: (count, length) = packets_per[second] count += 1 length += len(packet.bytes) packets_per[second] = (count, length) except KeyError: packets_per[second] = (1, len(packet.bytes)) elif options.ppm is not None: ts = datetime.datetime.fromtimestamp(packet.timestamp) ms = ts.microsecond / 1000 msecond = ts.strftime("%H:%M:%S") msecond += (".%d") % ms while (len(msecond) < 12): msecond += '0' try: (count, length) = packets_per[msecond] count += 1 length += len(packet.bytes) packets_per[msecond] = (count, length) except KeyError: packets_per[msecond] = (1, len(packet.bytes)) elif options.ppu is not None: try: (count, length) = packets_per[packet.timestamp] count += 1 length += len(packet.bytes) packets_per[packet.timestamp] = (count, length) except KeyError: packets_per[packet.timestamp] = (1, len(packet.bytes)) print "%d packets in dumpfile" % packets print "%d unique source IPs" % len(srcmap) print "%d ARP packets" % arp_cnt print "%d IPv4 packets" % ip_cnt print "%d ICMPv4 packets" % icmp_cnt print "%d UDP packets" % udp_cnt print "%d TCP packets" % tcp_cnt print "Top source addresses were" hit_list = sorted(srcmap.itervalues(), reverse = True) length = len(hit_list) for i in xrange(length): for addr in srcmap.items(): if addr[1] == hit_list[i]: print "Address %s\t Count %s\t Percentage %f" % (inet_ntop(AF_INET, struct.pack('!L', addr[0])), addr[1], (float(addr[1]) / float(packets)) * float(100)) if options.ps is not None: try: file = open(options.ps, "w") except: print "Could not open file %s for writing." % options.ps for seconds in sorted(packets_per.keys()): hms = time.strftime("%H:%M:%S",time.localtime(seconds)) data = ("%s, %d, %d\n" % (hms, packets_per[seconds][0], packets_per[seconds][1])) file.write(data) elif options.ppm is not None: try: file = open(options.ppm, "w") except: print "Could not open file %s for writing." % options.ppm for mseconds in sorted(packets_per.keys()): data = ("%s, %d, %d\n" % (mseconds, packets_per[mseconds][0], packets_per[mseconds][1])) file.write(data) elif options.ppu is not None: try: file = open(options.ppu, "w") except: print "Could not open file %s for writing." % options.ppu for useconds in sorted(packets_per.keys()): dt = datetime.datetime.fromtimestamp(useconds) data = ("%s, %d, %d\n" % (dt.strftime("%H:%M:%S.%f"), packets_per[useconds][0], packets_per[useconds][1])) file.write(data) #cProfile.run('main()', "foo.prof") main() pcs-0.6/scripts/udp_echo.py0000664000175000017500000000350711255512624015621 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: udp_echo.py,v 1.2 2006/06/27 14:45:43 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This script uses PCS to send UDP echo packets (port 7) import pcs from pcs.packets.ipv4 import * from pcs.packets.udp import * from socket import * def main(): UDP4Connector("127.0.0.1", 7) main() pcs-0.6/scripts/expect2.py0000664000175000017500000000731511255512624015406 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the names of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: Bruce M. Simpson # # Description: Another demo of network-level "expect" functionality. import pcs import pcs.packets.ethernet as ethernet from pcs.packets.ipv4 import * import pcs.packets.ipv4 as ipv4 from pcs.packets.igmp import * from pcs.packets.igmpv2 import * import pcs.packets.igmp as igmp import pcs.packets.igmpv2 as igmpv2 import sys def main(): file = pcs.PcapConnector("fxp0") # First, build a chain and use it as a filter to match any IGMPv2 joins # seen on the network. m = ethernet.ethernet() / ipv4.ipv4() / \ igmp.igmp(type=IGMP_v2_HOST_MEMBERSHIP_REPORT) / igmpv2.igmpv2() t = 50 print "Waiting %d seconds to see an IGMPv2 report." % t try: file.expect([m], t) except pcs.TimeoutError: print "Timed out." sys.exit(1) # Now try it with a "contains" filter. # This will match any packet chain containing an IGMPv2 message. c = igmpv2.igmpv2() t = 50 print "Waiting %d seconds to see an IGMPv2 report using 'contains'." % t try: file.expect([c], t) except pcs.TimeoutError: print "Timed out." sys.exit(1) print "And the matching packet chain is:" print file.match # Define a match function to apply to a field. # We could really use some syntactic sugar for this... def contains_router_alert(lp, lf, rp, rf): for i in rf._options: if isinstance(i, pcs.TypeLengthValueField) and \ i.type.value == IPOPT_RA: return True return False # Create a "contains" filter consisting of a single IPv4 datagram # with a "Router Alert" option in the header. Strictly speaking the # option isn't needed, as above we define a function which is used # as a compare function for the option list field. c = ipv4.ipv4(options=[ipv4opt(IPOPT_RA)]) c.options.compare = contains_router_alert t = 50 print "Waiting %d seconds to see any IP packet containing a Router Alert option." % t try: file.expect([c], t) except pcs.TimeoutError: print "Timed out." sys.exit(1) print "And the matching packet chain is:" print file.match sys.exit(0) main() pcs-0.6/scripts/arpwhohas.py0000664000175000017500000000615511255512624016031 0ustar andreasandreas# Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: arpwhohas.py,v 1.1 2006/09/08 07:15:26 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A simple program to send ARP requests and replies. import pcs from pcs import * from pcs.packets.arp import * from pcs.packets.ethernet import * def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--interface", dest="interface", default=None, help="Network interface to send on.") parser.add_option("-t", "--target", dest="target", default=None, help="IPv4 target address to lookup.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="Ethernet source address to use.") parser.add_option("-p", "--ip_source", dest="ip_source", default=None, help="IPv4 source address to use.") (options, args) = parser.parse_args() arppkt = arp() arppkt.op = 1 arppkt.sha = ether_atob(options.ether_source) arppkt.spa = inet_atol(options.ip_source) arppkt.tha = "\x00\x00\x00\00\x00\x00" arppkt.tpa = inet_atol(options.target) ether = ethernet() ether.src = ether_atob(options.ether_source) ether.dst = "\xff\xff\xff\xff\xff\xff" ether.type = 0x806 packet = Chain([ether, arppkt]) output = PcapConnector(options.interface) out = output.write(packet.bytes, len(packet.bytes)) reply = output.readpkt() reply = output.readpkt() print reply print reply.data main() pcs-0.6/scripts/snarf.py0000664000175000017500000000425711255512624015147 0ustar andreasandreas# Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: snarf.py,v 1.1 2006/07/13 10:05:40 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A quick and dirty packet snooper that demo's the power of PCS import pcs from pcs.packets.ethernet import ethernet def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--interface", dest="interface", default=None, help="Which interface to snarf from.") (options, args) = parser.parse_args() snarf = pcs.PcapConnector(options.interface) while 1: packet = ethernet(snarf.read()) print packet print packet.data main() pcs-0.6/scripts/http_get.py0000664000175000017500000000422511255512624015647 0ustar andreasandreas# Copyright (c) 2005, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: http_get.py,v 1.1 2006/07/13 10:05:40 gnn Exp $ # # Author: George V. Neville-Neil # # Description: This script uses PCS to send UDP echo packets (port 7) import pcs from pcs.packets import http from socket import * def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-t", "--target", dest="target", default=None, help="Host to contact.") (options, args) = parser.parse_args() conn = pcs.TCP4Connector(options.target, 80) conn.write("GET / \n\n") result = conn.read(1024) page = http.http(result) print page main() pcs-0.6/scripts/dns_query.py0000664000175000017500000000614611255512624016046 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: dns_query.py,v 1.3 2006/09/01 07:45:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A PCS demo script that performs a simple DNS lookup. import pcs from pcs import * from pcs.packets.dns import * def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-a", "--address", dest="addr", default=None, help="Address of the domain name server.") parser.add_option("-u", "--udp", dest="udp", default=None, help="Use UDP instead of TCP.") (options, args) = parser.parse_args() if options.udp is not None: conn = UDP4Connector(options.addr, 53) else: conn = TCP4Connector(options.addr, 53) if (options.udp is None): header = dnsheader(tcp = True) else: header = dnsheader() header.id = 1 header.rd = 1 header.qdcount = 1 query = dnsquery() query.type = 1 query.query_class = 1 lab1 = dnslabel() lab1.name = "www" lab2 = dnslabel() lab2.name = "neville-neil" lab3 = dnslabel() lab3.name = "com" lab4 = dnslabel() lab4.name = "" packet = Chain([header, lab1, lab2, lab3, lab4, query]) if options.udp is None: header.length = 38 packet = Chain([header, lab1, lab2, lab3, lab4, query]) print packet print packet.bytes print len(packet.bytes) conn.write(packet.bytes) retval = conn.read(1024) print len(retval) print dnsheader(retval) conn.close() main() pcs-0.6/scripts/ddos_analyze.py0000664000175000017500000000712311255512624016505 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: A program using PCS to analyze a tcpdump file and give # data relateing to whether or not the file shows a DDOS. import pcs from pcs.packets.ipv4 import * from socket import inet_ntoa, inet_aton, ntohl def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-f", "--file", dest="file", default=None, help="tcpdump file to read from") parser.add_option("-m", "--max", dest="max", default=10, type=int, help="top N addresses to report") parser.add_option("-s", "--subnet-mask", dest="mask", default=None, help="subnetmask") parser.add_option("-n", "--network", dest="network", default=None, help="network we're looking at") (options, args) = parser.parse_args() file = pcs.PcapConnector(options.file) max = options.max mask = pcs.inet_atol(options.mask) network = pcs.inet_atol(options.network) done = False srcmap = {} packets = 0 in_network = 0 while not done: try: packet = file.readpkt() except: done = True packets += 1 ip = packet.data if (ip.src & mask) != network: if ip.src in srcmap: srcmap[ip.src] += 1 else: srcmap[ip.src] = 1 else: in_network +=1 print "%d packets in dumpfile" % packets print "%d unique source IPs" % len(srcmap) print "%d packets in specified network" % in_network print "Top %d source addresses were" % max hit_list = sorted(srcmap.itervalues(), reverse = True) for i in range(1,max): for addr in srcmap.items(): if addr[1] == hit_list[i]: print "Address %s\t Count %s\t Percentage %f" % (inet_ntop(AF_INET, struct.pack('!L', addr[0])), addr[1], (float(addr[1]) / float(packets)) * float(100)) main() pcs-0.6/scripts/pcap_slice.py0000664000175000017500000000624611255512624016140 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: George V. Neville-Neil # # Description: A program using PCS to analyze a tcpdump file and give # data relateing to whether or not the file shows a DDOS. import pcs from pcs.packets.ipv4 import * from socket import inet_ntoa import array def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-i", "--in", dest="infile", default=None, help="pcap file to read from") parser.add_option("-o", "--out", dest="outfile", default=None, help="pcap file to write to") parser.add_option("-f", "--first", dest="first", default=0, type=int, help="first packet to start at") parser.add_option("-l", "--last", dest="last", default=None, type=int, help="last packet to keep") (options, args) = parser.parse_args() infile = pcs.PcapConnector(options.infile) outfile = pcs.PcapDumpConnector(options.outfile, infile.dlink) first = options.first last = options.last done = False packets = 0 written = 0 while not done: try: packet = infile.read() except: done = True packets += 1 if packets < first: continue if packets >= last: done = True outfile.write(packet) written +=1 print "%d packets copied from %s to %s" % (written, options.infile, options.outfile) main() pcs-0.6/scripts/dvmrp_ask_neighbors2.py0000664000175000017500000000654211255512624020145 0ustar andreasandreas#!/usr/bin/env python from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv2 import * from pcs.packets.dvmrp import * from pcs.packets.payload import * from pcs import * from time import sleep # # Send a DVMRP "ask neighbors" query (basically, clone the mrinfo tool). # def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-G", "--ether_dest", dest="ether_dest", default=None, help="The gateway Ethernet destination address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-d", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ether_dest is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return if options.ip_dest is None: idst = INADDR_DVMRP_GROUP else: idst = inet_atol(options.ip_dest) c = ethernet(src=ether_atob(options.ether_source), \ dst=ether_atob(options.ether_dest)) / \ ipv4(ttl=1, src=inet_atol(options.ip_source), dst=idst) / \ igmp(type=IGMP_DVMRP, code=DVMRP_ASK_NEIGHBORS2) / \ dvmrp(capabilities=DVMRP_CAP_DEFAULT, minor=0xFF, major=3) # # DVMRP "ask neighbors" does not contain the Router Alert option, # because DVMRP traffic is usually tunneled, and we don't need to # wake up every router on the path. # # The Ask_neighbors2 payload is: reserved, caps, minor, major: # 0x00, 0E, 0xFF, 0x03 is how mrinfo fills this out (DVMRPv3 compliant). # # PIM itself knows nothing about these messages, however, a DVMRP router # which handles these messages MAY tell you if it's peering with other # PIM routers (I believe only Ciscos do this). # c.calc_lengths() c.calc_checksums() c.encode() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) # # Wait for up to 'count' responses to the query to arrive and print them. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if chain.packets[2].type == IGMP_DVMRP: print chain.packets[2].println() #print "%s is in %s" % \ # (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \ # inet_ntop(AF_INET, struct.pack('!L', chain.packets[2].group))) count -= 1 main() pcs-0.6/scripts/igmp_v3_query.py0000664000175000017500000001422011255512624016616 0ustar andreasandreas#!/usr/bin/env python from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv3 import * from pcs.packets.payload import * from pcs import * from time import sleep # Send an IGMPv3 query. General, group-specific, or # group-and-source-specific queries are supported. def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-g", "--ether_dest", dest="ether_dest", default=None, help="The host Ethernet destination address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-D", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group to query.") parser.add_option("-S", "--igmp_sources", dest="igmp_sources", default=None, help="Comma-delimited list of IPv4 sources for " "a group-and-source specific query.") parser.add_option("-M", "--igmp_maxresp", dest="igmp_maxresp", default=None, help="The maximum time for end-stations to " "respond (in seconds).") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") parser.add_option("-2", "--igmp_v2_listen", action="store_true", dest="igmp_v2_listen", help="Listen for responses from IGMPv2 end-stations.") parser.add_option("-R", "--igmp_robustness", dest="igmp_robustness", default=None, help="Querier Robustness (default 2)") parser.add_option("-Q", "--igmp_qqic", dest="igmp_qqic", default=None, help="Querier's Query Interval (default 10s)") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return #if options.ip_dest is not None and options.ether_dest is None: # print "Non-optional argument missing." # return maxresp = 10 * 10 if options.igmp_maxresp is not None: maxresp = int(options.igmp_maxresp) * 10 # in units of deciseconds # # Parse source list for a GSR query. # sources = [] if options.igmp_sources is not None: if options.igmp_group is None: raise "A group must be specified for a GSR query." else: for source in options.igmp_sources.split(','): sources.append(inet_atol(source)) if len(sources) == 0: raise "Error parsing source list." # Set up the vanilla packet if options.ether_dest is not None: edst = ether_atob(options.ether_dest) else: edst = ETHER_MAP_IP_MULTICAST(INADDR_ALLHOSTS_GROUP) c = ethernet(src=ether_atob(options.ether_source), dst=edst) / \ ipv4(flags=IP_DF, ttl=1, src=inet_atol(options.ip_source)) / \ igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \ igmpv3.query() ip = c.packets[1] q = c.packets[3] # IGMPv3 General Queries are always sent to ALL-SYSTEMS.MCAST.NET. # However we allow this to be overidden for protocol testing -- Windows, # in particular, doesn't seem to respond. # # We expect reports on 224.0.0.22. # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. if options.igmp_robustness is not None: q.qrv = int(options.igmp_robustness) else: q.qrv = 2 # SHOULD NOT be 1, MUST NOT be 0 if options.igmp_qqic is not None: q.qqic = int(options.igmp_qqic) else: q.qqic = 10 # I query every 10 seconds if options.igmp_group is None: # General query. if options.ip_dest is not None: ip.dst = inet_atol(options.ip_dest) else: ip.dst = INADDR_ALLHOSTS_GROUP q.group = INADDR_ANY else: # Group-specific query, possibly with sources. if options.ip_dest is not None: ip.dst = inet_atol(options.ip_dest) else: ip.dst = inet_atol(options.igmp_group) q.group = ip.dst if IN_MULTICAST(ip.dst) is True and \ options.ether_dest is None: c.packets[0].dst = ETHER_MAP_IP_MULTICAST(ip.dst) for src in sources: q.sources.append(pcs.Field("", 32, default = src)) c.fixup() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) # # Wait for up to 'count' responses to the query to arrive and print them. # If options.igmp_v2_listen is True, also count responses from # end-stations which respond with IGMPv2. # # TODO: Pretty-print IGMPv3 reports. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if ((chain.packets[2].type == IGMP_v3_HOST_MEMBERSHIP_REPORT) or ((chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT) and \ (options.igmp_v2_listen is True))): version = 3 if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT: version = 2 #print chain.packets[2].println() print "%s responded to query with IGMPv%d." % \ ((inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src))), version) count -= 1 main() pcs-0.6/scripts/expect3.py0000664000175000017500000000525311255512624015406 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the names of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: Bruce M. Simpson # # Description: Simple demo of network-level "expect" functionality. import sys def main(): from pcs import PcapConnector, TimeoutError, LimitReachedError from pcs.packets.ethernet import ethernet from pcs.packets.ipv4 import ipv4 from pcs.packets.icmpv4 import icmpv4 from pcs.packets.icmpv4 import icmpv4echo from pcs.packets.icmpv4 import ICMP_ECHO #from pcs.packets.icmpv4 import ICMP_ECHOREPLY fxp0 = PcapConnector("fxp0") filter = ethernet() / ipv4() / icmpv4(type=ICMP_ECHO) / icmpv4echo() #from pcs.bpf import program #bp = fxp0.make_bpf_program(filter) #for lp in bp.disassemble(): # print lp #fxp0.setfilter('icmp') #fxp0.set_bpf_program(bp) print "Expecting at least 1 ICMP echo request within 10 seconds." try: fxp0.expect([filter], 10) except LimitReachedError: print "Limit reached." sys.exit(1) except TimeoutError: print "Timed out." sys.exit(1) nmatches = 0 if fxp0.matches is not None: nmatches = len(fxp0.matches) print "Matched", nmatches, "chain(s)." sys.exit(0) main() pcs-0.6/scripts/ping.py0000664000175000017500000000772211255512624014773 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2006, Neville-Neil Consulting # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the name of Neville-Neil Consulting nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: ping.py,v 1.3 2006/09/05 07:30:56 gnn Exp $ # # Author: George V. Neville-Neil # # Description: A simple re-implementatoin of the ping(8) program in # Python using the Packet Construction Set from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.icmpv4 import * from pcs.packets.payload import * from pcs import * from time import sleep def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-c", "--count", dest="count", default=1, help="Stop after sending (and recieving) count ECHO_RESPONSE packets..") parser.add_option("-D", "--dont_fragment", dest="df", default=False, help="Set the Don't Fragment bit.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-d", "--ip_dest", dest="ip_dest", default=None, help="The IP destination address.") parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-g", "--ether_dest", dest="ether_dest", default=None, help="The gateway Ethernet destination address.") (options, args) = parser.parse_args() c = ethernet(src=ether_atob(options.ether_source), \ dst=ether_atob(options.ether_dest)) / \ ipv4(ttl=64, src=inet_atol(options.ip_source), \ dst=inet_atol(options.ip_dest)) / \ icmpv4(type=8) / icmpv4echo(id=12345) / payload(payload="foobar") c.calc_lengths() # # Increment ICMP echo sequence number with each iteration. # output = PcapConnector(options.ether_iface) ip = c.packets[1] echo = c.packets[3] count = int(options.count) while (count > 0): c.calc_checksums() c.encode() out = output.write(c.bytes, len(c.bytes)) # packet = input.read() # print packet sleep(1) count -= 1 ip.id += 1 echo.sequence += 1 main() pcs-0.6/scripts/igmp_v2_query.py0000664000175000017500000000617311255512624016625 0ustar andreasandreas#!/usr/bin/env python from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv2 import * from pcs.packets.payload import * from pcs import * from time import sleep # Send an IGMPv2 general or group-specific query. def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group for a group-specific query. " "If omitted, send a general query.") parser.add_option("-M", "--maxresp", dest="igmp_maxresp", default=None, help="The maximum time for end-stations to respond " "(in seconds).") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after receiving at least count responses.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return maxresp = 3 * 10 if options.igmp_maxresp is not None: maxresp = int(options.igmp_maxresp) * 10 # in units of deciseconds if options.igmp_group is None: # General query. dst = INADDR_ALLHOSTS_GROUP group = INADDR_ANY else: # Group-specific query. dst = inet_atol(options.igmp_group) group = dst # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(dst)) / \ ipv4(flags=IP_DF, ttl=1, \ src=inet_atol(options.ip_source), \ dst=dst) / \ igmp(type=IGMP_HOST_MEMBERSHIP_QUERY, code=maxresp) / \ igmpv2(group=group) c.fixup() input = PcapConnector(options.ether_iface) input.setfilter("igmp") output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) # # Wait for up to 'count' responses to the query to arrive and print them. # count = int(options.count) while count > 0: packet = input.readpkt() chain = packet.chain() if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT: #print chain.packets[2].println() print "%s is in %s" % \ (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \ inet_ntop(AF_INET, struct.pack('!L', chain.packets[3].group))) count -= 1 main() pcs-0.6/scripts/igmp_monitor.py0000664000175000017500000000261011255512624016530 0ustar andreasandreas#!/usr/bin/env python from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv2 import * from pcs.packets.payload import * from pcs import * from time import sleep def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") #parser.add_option("-c", "--count", # dest="count", default=None, # help="Stop after receiving at least count responses.") (options, args) = parser.parse_args() if options.ether_iface is None: print "Non-optional argument missing." return input = PcapConnector(options.ether_iface) input.setfilter("igmp") # # Wait for up to 'count' responses to the query to arrive and print them. # quit = False while not quit: packet = input.readpkt() chain = packet.chain() print chain #if chain.packets[2].type == IGMP_v2_HOST_MEMBERSHIP_REPORT: # #print chain.packets[2].println() # print "%s is in %s" % \ # (inet_ntop(AF_INET, struct.pack('!L', chain.packets[1].src)), \ # inet_ntop(AF_INET, struct.pack('!L', chain.packets[3].group))) # count -= 1 main() pcs-0.6/scripts/igmp_v2_leave.py0000664000175000017500000000370111255512624016546 0ustar andreasandreas#!/usr/bin/env python from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv2 import * from pcs.packets.payload import * from pcs import * from time import sleep # Spoof an IGMPv2 HOST LEAVE message. def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group to spoof a leave message for.") parser.add_option("-A", "--no-router-alert", action="store_true", dest="no_ra", help="Disable the use of the IP Router Alert option.") (options, args) = parser.parse_args() if options.igmp_group is None or \ options.ether_source is None or \ options.ether_iface is None or \ options.ip_source is None: print "A required argument is missing." return output = PcapConnector(options.ether_iface) c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRTRS_GROUP)) / \ ipv4(flags=IP_DF, id=123, ttl=1, \ src=inet_atol(options.ip_source), \ dst=INADDR_ALLRTRS_GROUP) / \ igmp(type=IGMP_HOST_LEAVE_MESSAGE) / \ igmpv2(group=inet_atol(options.igmp_group)) c.fixup() out = output.write(c.bytes, len(c.bytes)) main() pcs-0.6/scripts/expect.py0000664000175000017500000000515111255512624015320 0ustar andreasandreas#!/usr/bin/env python # Copyright (c) 2008, Bruce M. Simpson. # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # Neither the names of the authors nor the names of contributors may be # used to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # # File: $Id: $ # # Author: Bruce M. Simpson # # Description: Simple demo of network-level "expect" functionality. import pcs from pcs.packets.udp import * from pcs.packets.tcp import * from pcs.packets.ipv4 import * from pcs.packets.ethernet import * from pcs.packets.arp import * import pcs.packets.ethernet as ethernet import pcs.packets.arp as arp import sys def main(): file = pcs.PcapConnector("fxp0") # Construct a filter chain. we are only interested in 3 fields. a = ethernet.ethernet() / arp.arp() a.wildcard_mask() a.packets[0].wildcard_mask(["type"], False) a.packets[1].wildcard_mask(["pro", "op"], False) a.packets[1].pro = 0x0800 # ETHERTYPE_IP (default) a.packets[1].op = 1 # ARPOP_REQUEST print "Waiting 10 seconds to see an ARP query." try: file.expect([a], 10) except pcs.TimeoutError: print "Timed out." sys.exit(1) print "And the matching packet chain is:" print file.match sys.exit(0) # TODO: Add the ability to match more complex filters # e.g. ar_spa == ar_tpa which is gratuitous arp. main() pcs-0.6/scripts/igmp_v3_leave.py0000664000175000017500000000440211255512624016546 0ustar andreasandreas#!/usr/bin/env python from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv3 import * from pcs.packets.payload import * from pcs import * from time import sleep # Send a spoof IGMPv3 report which says we've left the given group. def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group to spoof an IGMPv3 leave for.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.igmp_group is None: print "Non-optional argument missing." return # Create an IGMPv3 change-to-include report for the given group # with no sources, which means we're leaving the group. # IGMPv3 Host Reports are always sent to IGMP.MCAST.NET (224.0.0.22), # and must always contain the Router Alert option. c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(INADDR_ALLRPTS_GROUP)) / \ ipv4(src=inet_atol(options.ip_source), dst=INADDR_ALLRPTS_GROUP, \ ttl=1, flags=IP_DF, options=[ipvt4opt(IPOPT_RA)]) / \ igmp(type=IGMP_v3_HOST_MEMBERSHIP_REPORT) / \ igmpv3.report(records=[GroupRecordField("", \ group=inet_atol(options.igmp_group), \ type=IGMP_CHANGE_TO_INCLUDE)]) c.fixup() # Send it. output = PcapConnector(options.ether_iface) out = output.write(c.bytes, len(c.bytes)) main() pcs-0.6/scripts/bootp_server.py0000664000175000017500000001362711255512624016550 0ustar andreasandreas#!/usr/bin/env python # Not useful with Busybox udhcpc, which does not accept BOOTP replies. # # Also, for this to work properly with tap interfaces and PCAP, your # QEMU instances really need to be in sync with the addresses # assigned to the tap interfaces -- otherwise the outgoing traffic # will just get dropped, unless you source the traffic from a bridge # interface. # TODO: Update for the new checksum world order. import random from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.udpv4 import * from pcs.packets.dhcpv4 import * from pcs import * from time import sleep gw = "10.1.1.17" subnet = "255.255.255.0" # note: leading zeroes must be trimmed. map = { "52:54:0:12:34:56": "192.168.0.2" } def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-d", "--devname", dest="devname", default=None, help="The name of the tap device to open.") parser.add_option("-i", "--ifname", dest="ifname", default=None, help="The name of the interface to listen on.") parser.add_option("-g", "--group", dest="group", default=None, help="The IPv4 group to use for UML-style multicasts.") parser.add_option("-p", "--port", dest="port", default=None, help="The IPv4 port to use for UML-style multicasts.") parser.add_option("-a", "--ifaddr", dest="ifaddr", default=None, help="The IP address to listen on.") parser.add_option("-S", "--ether_source", dest="ether_source", default=None, help="The Ethernet address to listen on.") (options, args) = parser.parse_args() if options.devname is not None: input = TapConnector(options.devname) output = input elif options.group is not None: if options.port is None: print "Non-optional argument missing." return # XXX Currently, UmlMcast4Connector has to use the same broken # semantics as QEMU does, to see its traffic -- apps SHOULD be # joining groups on specific interfaces. # Note that we'll also end up seeing our own traffic. #input = UmlMcast4Connector(options.group, options.port, options.ifaddr) input = UmlMcast4Connector(options.group, options.port, "0.0.0.0") output = input elif options.ifname is not None: input = PcapConnector(options.ifname) output = PcapConnector(options.ifname) input.setfilter("udp port 67 or udp port 68") if options.ifaddr is None or \ options.ether_source is None: print "Non-optional argument missing." return ifaddr = inet_atol(options.ifaddr) ether_source = ether_atob(options.ether_source) ip_id = int(random.random() * 32768) # XXX Should really have an API for extracting our # local ethernet address. running = True while running is True: packet = input.readpkt() chain = packet.chain() # Must have: ether + ip + udp + dhcp. # UDP checksum ignored. Assume pcap filter above did its job. if len(chain.packets) < 4 or \ not isinstance(chain.packets[3], dhcpv4): continue i_ether = chain.packets[0] i_ip = chain.packets[1] i_udp = chain.packets[2] i_dhcp = chain.packets[3] # check dhcp htype is ethernet. # check if dhcp.cid in map. if i_dhcp.op != pcs.packets.dhcpv4.BOOTREQUEST or \ i_dhcp.htype != pcs.packets.dhcpv4.HTYPE_ETHER or \ i_dhcp.hlen != 6: continue #print i_dhcp chaddr_s = ether_btoa(i_dhcp.chaddr[:i_dhcp.hlen]) if not chaddr_s in map: print "%s not in map" % chaddr_s continue ciaddr = inet_atol(map[chaddr_s]) # from map dhcp = dhcpv4() dhcp.op = pcs.packets.dhcpv4.BOOTREPLY dhcp.htype = pcs.packets.dhcpv4.HTYPE_ETHER dhcp.hlen = 6 dhcp.hops = 0 dhcp.xid = i_dhcp.xid dhcp.flags = 0 #dhcp.ciaddr = ciaddr dhcp.siaddr = ifaddr # XXX should only fill out if i_dhcp.ciaddr was 0.0.0.0 dhcp.yiaddr = ciaddr dhcp.chaddr = i_dhcp.chaddr #dhcp.sname = "myhost" #dhcp.file = "/vmunix" #dhcp.options.append(dhcpv4_options.cookie().field()) # server ID. # XXX Weeiiird! #sid = dhcpv4_options.dhcp_server_identifier() #sid.value = ifaddr #sid.value = inet_atol("0.0.0.0") #dhcp.options.append(sid.field()) # Subnet mask. #sm = dhcpv4_options.subnet_mask() #sm.value = inet_atol("255.255.255.0") #dhcp.options.append(sm.field()) # Default gateway. #dg = dhcpv4_options.routers() #dg.value = ifaddr #dhcp.options.append(dg.field()) # Add end marker. #end = dhcpv4_options.end() #dhcp.options.append(end.field()) # Pad BOOTP payload to 32-bit width. # XXX BOOTP is problematic because the field which contains # the options needs to be clamped to 64 bytes in total. This # means we need to know the encoded length of each option. # For now, guess it... total length of an RFC-951 payload # is always 300 bytes. # this shuts up wireshark. #padlen = 300 - (len(dhcp.bytes) % 4) #padlen = 50 - (len(dhcp.bytes) % 4) #padlen = 4 #pad = dhcpv4_options.pad(padlen) #dhcp.options.append(pad.field()) # Encapsulate ethernet. ether = ethernet() ether.type = 0x0800 ether.src = ether_source ether.dst = i_dhcp.chaddr[:i_dhcp.hlen] # Encapsulate IPv4. ip = ipv4() ip.version = 4 ip.hlen = 5 ip.tos = 0 ip.id = ip_id ip.flags = 0x00 ip.offset = 0 ip.ttl = 1 ip.protocol = IPPROTO_UDP ip.src = ifaddr ip.dst = ciaddr ip_id += 1 # Encapsulate UDPv4. udp = udpv4() udp.sport = 67 udp.dport = 68 udp.length = len(dhcp.bytes) udp.checksum = udp.cksum(ip, dhcp.bytes) # Compute header checksums. ip.length = len(ip.bytes) + len(udp.bytes) + len(dhcp.bytes) ip.checksum = ip.cksum() # Send the lot. packet = Chain([ether, ip, udp, dhcp]) packet.encode() out = output.write(packet.bytes, len(packet.bytes)) print out main() pcs-0.6/scripts/igmp_v2_join.py0000664000175000017500000000517011255512624016413 0ustar andreasandreas#!/usr/bin/env python from pcs.packets.localhost import * from pcs.packets.ethernet import * from pcs.packets.ipv4 import * from pcs.packets.igmp import * from pcs.packets.igmpv2 import * from pcs.packets.payload import * from pcs import * from time import sleep import sys # Send an IGMPv2 general or group-specific query. def main(): from optparse import OptionParser parser = OptionParser() parser.add_option("-I", "--ether_iface", dest="ether_iface", default=None, help="The name of the source interface.") parser.add_option("-e", "--ether_source", dest="ether_source", default=None, help="The host Ethernet source address.") parser.add_option("-s", "--ip_source", dest="ip_source", default=None, help="The IP source address.") parser.add_option("-G", "--igmp_group", dest="igmp_group", default=None, help="The IPv4 group for a group-specific query. " "If omitted, send a general query.") parser.add_option("-S", "--seconds", dest="seconds", default=1.0, help="Number of seconds between packets.") parser.add_option("-c", "--count", dest="count", default=None, help="Stop after sending count packets.") (options, args) = parser.parse_args() if options.ether_iface is None or \ options.ether_source is None or \ options.ip_source is None or \ options.count is None: print "Non-optional argument missing." return maxresp = 3 * 10 if options.igmp_group is None: # General query. dst = INADDR_ALLHOSTS_GROUP group = INADDR_ANY else: # Group-specific query. dst = inet_atol(options.igmp_group) group = dst # Queries don't contain the Router Alert option as they are # destined for end stations, not routers. c = ethernet(src=ether_atob(options.ether_source), \ dst=ETHER_MAP_IP_MULTICAST(dst)) / \ ipv4(flags=IP_DF, ttl=1, \ src=inet_atol(options.ip_source), \ dst=dst) / \ igmp(type=IGMP_v2_HOST_MEMBERSHIP_REPORT, code=maxresp) / \ igmpv2(group=group) c.fixup() output = PcapConnector(options.ether_iface) # # Send count packets, delayed by seconds # count = int(options.count) if count < 0: count = sys.maxint while count > 0: out = output.write(c.bytes, len(c.bytes)) count -= 1 sleep(float(options.seconds)) main()