:mod:`scamper` --- interact with scamper processes and data .. module:: scamper :synopsis: interact with scamper processes and data -------------- Introduction ------------ `scamper `_ is a tool that actively probes the Internet in order to analyze Internet topology and performance. The scamper tool provides rich functionality, this :mod:`scamper` module provides convenient classes and methods for interacting with scamper processes and data. The module has two related halves -- those for interacting with running scamper processes (through :class:`ScamperCtrl` and related classes) and those for reading and writing data previously collected with scamper (:class:`ScamperFile`). These classes are supported by other classes that store measurement results. The types of measurements supported by this module include ping, traceroute, alias resolution, DNS queries, HTTP, UDP probes, and packet capture. Interacting with Scamper Processes ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Simple Parallel Measurement ^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following example implements the well-known single-radius measurement technique, which conducts delay measurements to an IP address from a distributed set of vantage points, and reports the shortest of all the observed delays with the name of the vantage point that observed the delay. The :class:`ScamperCtrl` object is instantiated with a single parameter that identifies a directory that contains a set of Unix domain sockets, each of which represents a vantage point running scamper; the :class:`ScamperCtrl` object makes these vantage points available via :meth:`~scamper.ScamperCtrl.instances`, which the caller uses to conduct a ping measurement via each of them. These ping measurements operate in parallel -- the ping measurements on each of the nodes operate asynchronously. We then collect the results of the measurements, noting the minimum observed delay, and the vantage point where it came from. We pass a 10-second timeout to :meth:`~scamper.ScamperCtrl.responses` so that if a vantage point experiences an outage after we send the measurements, it would not hold up the whole experiment. Finally, we print the result of the measurement. .. code-block:: import sys from datetime import timedelta from scamper import ScamperCtrl if len(sys.argv) != 3: print("usage: single-radius.py $dir $ip") sys.exit(-1) ctrl = ScamperCtrl(remote_dir=sys.argv[1]) for i in ctrl.instances(): ctrl.do_ping(sys.argv[2], inst=i) min_rtt = None min_vp = None for o in ctrl.responses(timeout=timedelta(seconds=10)): if o.min_rtt is not None and (min_rtt is None or min_rtt > o.min_rtt): min_rtt = o.min_rtt min_vp = o.inst if min_rtt is not None: print(f"{min_vp.name} {(min_rtt.total_seconds()*1000):.1f} ms") else: print(f"no responses for {sys.argv[2]}") Reactive Measurement ^^^^^^^^^^^^^^^^^^^^ The next example shows a more complex measurement. Let's say we want to know the RTTs to the authoritative name servers for a zone from a single vantage point. This implementation takes two parameters -- a single vantage point, and a zone name to study. We open an interface to that VP, and then issue a DNS query for the authoritative name servers for the zone from that VP. There are a couple of interesting things to note. First, we do not pass a handle representing the VP instance to the :meth:`~scamper.ScamperCtrl.do_dns` method, as the :class:`ScamperCtrl` interface only has a single instance associated with it -- it is smart enough to use that single instance for the measurement. Second, we pass *sync* = ``True`` to make the measurement synchronous -- the method does not return until it has the results of that single measurement. This is shorter (in terms of lines of code) and more readable than issuing an asynchronous measurement and then collecting the single result. Then, we issue asynchronous queries for the IPv4 and IPv6 addresses for the name servers returned and send ping measurements for each of the addresses. Finally, we print the names of the nameservers, their IP addresses, and the minimum RTT observed to each. .. code-block:: import sys from datetime import timedelta from scamper import ScamperCtrl if len(sys.argv) != 3: print("usage: authns-delay.py $vp $zone") sys.exit(-1) ctrl = ScamperCtrl(remote=sys.argv[1]) # get the list of NS for the zone o = ctrl.do_dns(sys.argv[2], qtype='NS', wait_timeout=1, sync=True) # issue queries for the IP addresses of the authoritative servers for ns in o.ans_nses(): ctrl.do_dns(ns, qtype='A', wait_timeout=1) ctrl.do_dns(ns, qtype='AAAA', wait_timeout=1) # collect the unique addresses out of the address lookups addr = {} for o in ctrl.responses(timeout=timedelta(seconds=3)): for a in o.ans_addrs(): addr[a] = o.qname # collect RTTs for the unique IP addresses for a in addr: ctrl.do_ping(a) for o in ctrl.responses(timeout=timedelta(seconds=10)): print(f"{addr[o.dst]} {o.dst} " + (f"{(o.min_rtt.total_seconds() * 1000):.1f}" if o.min_rtt is not None else "???")) Dynamic Event-driven Measurement ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The module also supports a more dynamic approach to interacting with many vantage points that each signal their desire for more work. The following code maintains a list of addresses per vantage point to ping. The *vps* dictionary maintains a mapping of :class:`ScamperInst` to that list of addresses. When each instance signals that it is ready for more work, the *morecb* is called, with the overall :class:`ScamperCtrl`, the specific :class:`ScamperInst` that wants another measurement, and the *param* specified to the :class:`ScamperCtrl` constructor. .. code-block:: import sys from scamper import ScamperCtrl from datetime import timedelta @staticmethod def _feedme(ctrl, inst, vps): if len(vps[inst]) == 0: inst.done() else: ctrl.do_ping(vps[inst].pop(0), inst=inst) @staticmethod def _main(vps): vps = {} ctrl = ScamperCtrl(morecb=_feedme, param=vps) for vp in vps: inst = ctrl.add_remote(vp) vps[inst] = ["192.0.2.1", "192.0.2.2", "192.0.2.3"] # issue measurements as each VP asks for a new measurement while not ctrl.is_done(): o = None try: o = ctrl.poll(timeout=timedelta(seconds=10)) except Exception as e: print(f"got exception {e}") continue # if ctrl.poll() returns None, either all measurements are # complete, or we timed out. say what happened. if o is None: if ctrl.is_done(): print("done") else: print("timed out") break print(f"{o.inst.name} {o.dst} {o.min_rtt}") return 0 if __name__ == "__main__": sys.exit(_main(sys.argv[1:])) The module supports many different types of measurements: #. Traceroute via :meth:`~scamper.ScamperCtrl.do_trace` #. Ping via :meth:`~scamper.ScamperCtrl.do_ping` #. Alias resolution via :meth:`~scamper.ScamperCtrl.do_ally`, :meth:`~scamper.ScamperCtrl.do_mercator`, :meth:`~scamper.ScamperCtrl.do_midarest`, :meth:`~scamper.ScamperCtrl.do_midardisc`, :meth:`~scamper.ScamperCtrl.do_prefixscan`, and :meth:`~scamper.ScamperCtrl.do_radargun` #. DNS via :meth:`~scamper.ScamperCtrl.do_dns` #. Packet capture via :meth:`~scamper.ScamperCtrl.do_sniff` #. MDA traceroute via :meth:`~scamper.ScamperCtrl.do_tracelb` #. HTTP via :meth:`~scamper.ScamperCtrl.do_http` #. UDP probes via :meth:`~scamper.ScamperCtrl.do_udpprobe` Reading and Writing Files ~~~~~~~~~~~~~~~~~~~~~~~~~ To read results stored in a native scamper :manpage:`warts(5)` file, instantiate a :class:`ScamperFile` object, passing the name of the file to open as the first parameter. Read each object out of the file using the :meth:`~scamper.ScamperFile.read` method, or by using the built in Iterator, demonstrated below. If the file contains objects of different types, but you are only interested in a subset of the object types, you can signal the types with the :meth:`~scamper.ScamperFile.filter_types` method, or by signalling that with the constructor. Finally, you can close the file when you are finished using the :meth:`~scamper.ScamperFile.close` method. The following code illustrates the overall approach: .. code-block:: from scamper import ScamperFile, ScamperTrace addrs = {} file = ScamperFile("foo.warts.gz") for o in file: if isinstance(o, ScamperTrace): for hop in o.hops(): if hop.addr is not None: addrs[hop.addr] = 1 file.close() for o in sorted(list(addrs)): print(o) This code reads :class:`ScamperTrace` objects out of foo.warts.gz, storing addresses observed in each traceroute in a dictionary to identify the unique addresses. Finally, it prints the addresses in sorted order. To write measurements to a file, instantiate a :class:`ScamperFile` object, passing 'w' as the mode parameter. By default, :class:`ScamperFile` will write :manpage:`warts(5)` output, but this can be changed either by specifying the kind parameter, or by using an appropriate suffix in the filename. :class:`ScamperFile` can write compressed :manpage:`warts(5)` output using "warts.gz", "warts.bz2", or "warts.xz", write json output with "json", or simple text output with "text". Write each object out by passing the object to the :meth:`~scamper.ScamperFile.write` method. If you wish to save measurement results collected via a :class:`ScamperCtrl`, then open a file, and pass it to the :class:`ScamperCtrl` constructor. .. code-block:: from scamper import ScamperCtrl, ScamperFile outfile = ScamperFile("foo.warts.gz", 'w') ctrl = ScamperCtrl(remote_dir="/tmp/dir", outfile = outfile) This way, :class:`ScamperCtrl` will record all measurement objects in the file, so that you do not have to :meth:`~scamper.ScamperFile.write` them yourself. API Reference ------------- Classes for Managing Scamper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :class:`ScamperCtrl` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperCtrl(meta=False, morecb=None, eofcb=None, param=None,\ unix=None, remote=None, remote_dir=None, outfile=None) :class:`ScamperCtrl` objects provide an event-driven interface to one or more scamper processes, each of which is represented by a single :class:`ScamperInst` object. The general workflow is to instantiate a :class:`ScamperCtrl` object connected that manages one or more :class:`ScamperInst` objects, issue measurements via the various do methods, read and save results, and either issue new measurements or finish. The :class:`ScamperCtrl` constructor takes the following named parameters, all of which are optional. The *meta* parameter signals whether the caller wants meta objects (:class:`ScamperList`, :class:`ScamperCycle`) or not; the default is ``False``. The *morecb* parameter is a callback function that :class:`ScamperCtrl` will call when an scamper instance signals that it wants more work. The callback takes three parameters: a :class:`ScamperCtrl`, a :class:`ScamperInst`, and a user-supplied parameter that is passed to the callback to use. The *eofcb* parameter is a callback that :class:`ScamperCtrl` will call when an instance signals that it has finished. The callback takes the same three parameters as *morecb*. The *param* parameter is the user-supplied parameter that will be passed to *morecb* and *eofcb*. The *outfile* parameter identifies a :class:`ScamperFile` opened for writing that should record all measurement results. This can save the caller from writing code to store individual measurement results as these are passed to the caller. The *unix* parameter identifies the path in the file system to a unix domain socket representing a local scamper instance, which will then become accessible via a :class:`ScamperInst`. The *remote* parameter identifies the path in the file system to a unix domain socket representing a remote scamper instance, which will then become accessible via a :class:`ScamperInst`. The *remote_dir* parameter identifies the path to a directory in the file system containing multiple unix domain sockets, each of which represent a remote scamper instance that will become accessible via :class:`ScamperInst` objects. These first set of methods and attributes allow a program to manage and use a set of :class:`ScamperInst`. .. method:: add_unix(path) Add a single :class:`ScamperInst` which represents a local scamper process available via a Unix domain socket at the specified location in the file system identified with the *path* parameter. The method returns the :class:`ScamperInst` object to the caller. You do not have to store the object, as the :class:`ScamperCtrl` object also retains a reference to the :class:`ScamperInst`. You can also connect a local scamper process when constructing the :class:`ScamperCtrl` object by passing the path to the *unix* parameter in the constructor. This will save you writing code. Raises a :exc:`RuntimeError` if the path is invalid, or the caller does not have sufficient privileges in the file system to open the socket. .. method:: add_inet(port, addr=None) Add a single :class:`ScamperInst` which represents a scamper process available on a regular socket. The *port* parameter is mandatory. The *addr* parameter is optional. If not supplied, the *port* is assumed to refer to a local scamper instance which can be found on the loopback IP address. The method returns the :class:`ScamperInst` object to the caller. You do not have to store the object, as the :class:`ScamperCtrl` object also retains a reference to the :class:`ScamperInst`. Raises a :exc:`RuntimeError` if the port is invalid, or the caller cannot connect to the port. .. method:: add_remote(path) Add a single :class:`ScamperInst` which represents a scamper process on a remote system available via a Unix domain socket at the specified location in the file system identified with the *path* parameter. The method returns the :class:`ScamperInst` object to the caller. You do not have to store the object, as the :class:`ScamperCtrl` object also retains a reference to the :class:`ScamperInst`. You can also connect a remote scamper process when constructing the :class:`ScamperCtrl` object by passing the path to the *remote* parameter in the constructor. This will save you writing code. Raises a :exc:`RuntimeError` if the path is invalid, or the caller does not have sufficient privileges in the file system to open the socket. .. method:: add_remote_dir(path) Add a :class:`ScamperInst` for each remote system available via a Unix domain socket in the specified directory in the file system identified with the *path* parameter. You can also connect these systems when constructing the :class:`ScamperCtrl` object by passing the path to the *remote_dir* parameter in the constructor. This will save you writing code. Raises a :exc:`RuntimeError` if the path is invalid, or the caller does not have sufficient privileges in the file system to open a socket. .. method:: instances() Return a list of :class:`ScamperInst` managed by the :class:`ScamperCtrl`. This provides a convenient interface to issue commands to all available vantage points. .. attribute:: instc The total number of :class:`ScamperInst` managed by this :class:`ScamperCtrl`. The following methods provide interfaces for obtaining measurement results, as well as handling exceptions. .. method:: poll(timeout=None, until=None) Wait for a measurement result to become available from one of the :class:`ScamperInst` under management. The method will block until a result is available, or an exception occurs. The *timeout* parameter limits the time the method will block before returning, and is a :class:`~datetime.timedelta` object. The *until* parameter specifies when the method should return, if there is no result available by then, and is a :class:`~datetime.datetime` object. If an exception has occurred asynchronously, perhaps because a :class:`ScamperInst` rejected a command, or a user-provided callback function raised an exception, this method will raise it. .. method:: responses(timeout=None, until=None) Return all measurement results for all issued measurements, blocking until there are no issued measurements outstanding. The caller can limit the time this method will block by using the *timeout* and *until* parameters. The *timeout* parameter is a :class:`~datetime.timedelta` that specifies the length of time the responses generator can block before returning. The *until* parameter is a :class:`~datetime.datetime` that specifies when the method should return. This method will not raise any exceptions that get queued asynchronously by :class:`ScamperCtrl`. The caller should call the :meth:`~scamper.ScamperCtrl.exceptions` method to obtain exceptions after :meth:`~scamper.ScamperCtrl.responses` returns. .. method:: exceptions() This method returns queued exceptions. You should call this method after calling :meth:`~scamper.ScamperCtrl.responses`. .. method:: done() Signal that there is no further measurements to be issued on any of the connected :class:`ScamperInst`. .. method:: is_done() Returns ``True`` when all issued measurements have returned and all :class:`ScamperInst` have signalled end-of-file. .. attribute:: taskc The total number of tasks outstanding. The following methods provide interfaces for issuing measurements. Each of the :class:`ScamperCtrl` *do_* methods have three parameters in common, which we document here for brevity. The first, *sync*, determines whether the measurement operates synchronously or not. By default, a measurement operates asynchronously (*sync* = ``False``), and the *do_* methods return a :class:`ScamperTask` object that represents the measurement. When operating synchronously (*sync* = ``True``), the *do_* methods each return the result of the measurement when it becomes available. The second parameter in common is the *inst* parameter. This identifies the :class:`ScamperInst` that the measurement should be executed on. If the :class:`ScamperCtrl` object is operating with a single instance, then you do not have to pass an *inst* parameter -- it will use that single instance. Otherwise, you have to identify the specific :class:`ScamperInst` that the measurement should be executed on. The third common parameter is the *userid* parameter, which is an integer value that the caller can tag on the measurement for its own purpose. The value has to be able to be represented in an unsigned 32-bit integer, as that is what scamper uses internally. .. method:: do_trace(dst, confidence=None, dport=None, icmp_sum=None,\ firsthop=None, gaplimit=None, loops=None, hoplimit=None,\ pmtud=None, squeries=None, ptr=None, payload=None,\ method=None, attempts=None, all_attempts=None, rtr=None,\ sport=None, src=None, tos=None, wait_timeout=None,\ wait_probe=None, userid=None, inst=None, sync=False) Schedule a traceroute measurement to the IP address identified by *dst*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. The *confidence* parameter specifies a confidence level to reach before assuming all the interfaces have been observed that will reply at that hop, and can be either 95 or 99. *sport* and *dport* specify the (base) source and destination TCP/UDP ports to use in probes. *icmp_sum* specifies the checksum to use in the ICMP header for icmp-paris traceroute. *firsthop* specifies the TTL to start probing with. *gaplimit* specifies how many consecutive unresponsive hops before traceroute should stop. *loops* specifies the number of loops allowed before traceroute stops. *pmtud*, if ``True``, instructs scamper to do Path-MTU probing of the path, to identify MTU changes in the path. *squeries* specifies the number of consecutive hops to probe before stopping to wait for a response. *ptr*, if ``True``, instructs scamper to look up the name of any IP address observed in a response. *payload* specifies a :obj:`bytes` object with a payload to include in each probe. *method* specifies the type of probing strategy to use: icmp-paris, udp-paris, tcp, tck-ack, udp, or icmp. *attempts* specifies the number of attempts to try, per TTL; if *all_attempts* is ``True``, then all attempts are sent, otherwise scamper stops after receiving a response for the hop. *rtr* specifies the IP address of the first hop router, overriding the system's choice of router. *src* specifies the source IP address to use in probes. *tos* specifies the value to put in the 8-bit field previously known as IP Type of Service. *wait_timeout* specifies the length of time to wait for a response to a probe. *wait_probe* specifies the minimum length of time between consecutive probes. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperTrace` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_tracelb(dst, confidence=None, dport=None, firsthop=None,\ gaplimit=None, method=None, attempts=None, rtr=None,\ sport=None, tos=None, wait_timeout=None, wait_probe=None,\ userid=None, inst=None, sync=False) Schedule an MDA (load-balancer) traceroute measurement to the IP address identified by *dst*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. The *confidence* parameter specifies a confidence level to reach before assuming all the interfaces have been observed that will reply at that hop, and can be either 95 or 99. *sport* and *dport* specify the (base) source and destination TCP/UDP ports to use in probes. *firsthop* specifies the TTL to start probing with. *gaplimit* specifies how many consecutive unresponsive hops before traceroute should stop. *method* specifies the type of probing strategy to use: udp-dport, icmp-echo, udp-sport, tcp-sport, or tcp-ack-sport. *attempts* specifies the number of attempts to try, per TTL. *ptr*, if ``True``, instructs scamper to look up the name of any IP address observed in a response. *rtr* specifies the IP address of the first hop router, overriding the system's choice of router. *tos* specifies the value to put in the 8-bit field previously known as IP Type of Service. *wait_timeout* specifies the length of time to wait for a response to a probe. *wait_probe* specifies the minimum length of time between consecutive probes. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperTracelb` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_ping(dst, tcp_seq=None, tcp_ack=None, attempts=None,\ icmp_id=None, icmp_seq=None, icmp_sum=None, dport=None,\ sport=None, wait_probe=None, wait_timeout=None, tos=None,\ ttl=None, mtu=None, stop_count=None, method=None, payload=None,\ rtr=None, recordroute=None, size=None, src=None,\ userid=None, inst=None, sync=False) Schedule a ping measurement to the IP address identified by *dst*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. *tcp_seq* and *tcp_ack* specify the values to insert in the TCP sequence and acknowledgment fields. *attempts* specifies the number of probes to send. *icmp_id*, *icmp_seq*, and *icmp_sum* specify the ID, sequence, and checksum values to use in the ICMP header. *sport* and *dport* specify the source and destination port values for TCP and UDP probe methods. *wait_probe* and *wait_timeout* specify the length of time between probes, and how long to wait for a response to a probe. *tos* and *ttl* specify the type-of-service and TTL values to use in the IP header. *mtu* specifies a pseudo-MTU value to use for the measurement; if a response is larger, then scamper will send a packet too big to induce fragmentation in subsequent responses. *stop_count* specifies the number of probes that need a response before stopping. *method* specifies the probe strategy to use: icmp-echo, icmp-time, udp, udp-port, tcp-syn, tcp-syn-sport, tcp-synack, tcp-ack, tcp-ack-sport, or tcp-rst. *payload* specifies a :obj:`bytes` object with a payload to include in each probe. *rtr* specifies the IP address of the first hop router, overriding the system's choice of router. *recordroute*, if ``True``, includes an IP record-route option in probes. *size* specifies the size of probe packets to send. *src* specifies the source IP address to use in probes. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperPing` object if *sync* is ``True``. .. method:: do_dns(qname, server=None, qclass=None, qtype=None,\ attempts=None, rd=None, wait_timeout=None, tcp=None,\ userid=None, inst=None, sync=False) Schedule a DNS measurement for the name identified by *qname*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. *server* specifies the IP address of the DNS server to use. *qclass* specifies the class of query to make ('in' or 'ch'); by default, this is 'in'. *qtype* specifies the type of query to make ('a', 'aaaa', 'ptr', 'mx', 'ns', 'soa', 'txt'); by default, the query will be 'ptr' if an address is provided, else it will be an 'a' query. *attempts* specifies the number of queries to send before stopping. *rd*, if ``True``, signals to the DNS server that this is a recursive query. *tcp*, if ``True``, signals that the measurement should use TCP instead of UDP. *wait_timeout* specifies the length of time to wait for a response. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperHost` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_http(dst, url, headers=None, insecure=False,\ limit_time=None, userid=None, inst=None, sync=False) Schedule an HTTP GET to the IP address specified in *dst* using the URL specified in the *url* parameter. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. *headers* specifies a dictionary that maps header names to values to include in the GET request. *insecure*, if ``True``, allows scamper to ignore TLS certificate errors with an HTTPS and proceed with the request. *limit_time* specifies the maximum length of time that the HTTP query may take. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperHttp` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_udpprobe(dst, dport, payload, attempts=None,\ stop_count=None, inst=None, userid=None, sync=False) Send a UDP probe to the IP address and port specified by *dst* and *dport*, with the specified *payload*. *attempts* specifies the number of probes to send before stopping. *stop_count* specifies the number of probes that need a response before stopping. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperUdpprobe` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_ally(dst1, dst2, fudge=None, icmp_sum=None, dport=None,\ sport=None, method=None, attempts=None, wait_probe=None,\ wait_timeout=None, userid=None, inst=None, sync=False) Schedule an Ally-style alias resolution measurement for the two IP addresses identified by *dst1* and *dst2*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. The *fudge* value specifies the maximum difference between IPID values to still consider as possibly from the same counter. *icmp_sum* specifies the ICMP checksum value to use in probes. *sport* and *dport* specify the (base) source and destination ports to use in probes. *method* specifies the probing strategy: udp, udp-dport, tcp-ack, tcp-ack-sport, tcp-syn-sport, or icmp-echo. *attempts* specifies the total number of probes to send in this measurement. *wait_probe* and *wait_timeout* specify the length of time between probes, and how long to wait for a response to a probe. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperDealias` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_mercator(dst, userid=None, inst=None, sync=False) Conduct a Mercator-style alias resolution measurement to the IP address identified by *dst*. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperDealias` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_midarest(probedefs=None, addrs=None, rounds=None,\ wait_probe=None, wait_round=None, wait_timeout=None,\ userid=None, inst=None, sync=False) Conduct MIDAR-style estimation-stage probing of a list of IP addresses specified in the *addrs* parameter. The *probedefs* parameter must contain a list of :class:`ScamperDealiasProbedef` objects that define a probing method. Both *addrs* and *probedefs* are mandatory named parameters. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. The *rounds* parameter specifies how many rounds to conduct. *wait_probe*, *wait_round*, and *wait_timeout* specify the minimum time between probes, the minimum time between rounds, and the minimum time to wait for a response for a probe. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperDealias` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_midardisc(probedefs=None, schedule=None,\ startat=None, wait_timeout=None,\ userid=None, inst=None, sync=False) Conduct MIDAR-style discovery-stage probing using of a list :class:`ScamperDealiasProbedef` objects that each identify a method and IP address in the *probedefs* parameter, and a list of :class:`ScamperDealiasMidardiscRound` objects that specify individual rounds in the *schedule* parameter. Both *probedefs* and *schedule* are mandatory named parameters. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. *startat* specifies a unix timestamp when probing should commence, and *wait_timeout* specifies the length of time to wait for a response to a probe. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperDealias` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_radargun(probedefs=None, addrs=None, rounds=None,\ wait_probe=None, wait_round=None, wait_timeout=None,\ userid=None, inst=None, sync=False) Conduct radargun-style probing using a list of :class:`ScamperDealiasProbedef` objects that each identify a method in the *probedefs* parameter. Either all probedefs contain an IP address, or the IP addresses to probe will be found in *addrs*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. *rounds* specifies the number of rounds for this measurement. *wait_probe*, *wait_round*, and *wait_timeout* specify the minimum time between probes, the minimum time between rounds, and the minimum time to wait for a response for a probe. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperDealias` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_prefixscan(near, far, prefixlen, fudge=None,\ icmp_sum=None, dport=None, sport=None, method=None,\ attempts=None, wait_probe=None, wait_timeout=None,\ userid=None, inst=None, sync=False) Conduct a prefixscan measurement to infer an alias on the router with IP address *near* that is within a subnet containing *far*. This measurement requires the *near* and *far* addresses defining a link to probe, and the size of the prefix to search in *prefixlen*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. The *fudge* value specifies the maximum difference between IPID values to still consider as possibly from the same counter. *icmp_sum* specifies the ICMP checksum value to use in probes. *sport* and *dport* specify the (base) source and destination ports to use in probes. *method* specifies the probing strategy: udp, udp-dport, tcp-ack, tcp-ack-sport, tcp-syn-sport, or icmp-echo. *attempts* specifies the total number of attempts per probe, before moving onto the next address pair. *wait_probe* and *wait_timeout* specify the length of time between probes, and how long to wait for a response to a probe. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperDealias` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. .. method:: do_sniff(src, icmp_id, limit_pkt_count=None, limit_time=None,\ userid=None, inst=None, sync=False) Conduct a simple packet capture on the interface with the IP address in *src* for ICMP packets with an ICMP-ID value of *icmp_id*. The other parameters are optional; if they are not specified, then the scamper process that does the measurement will use its defaults. *limit_pkt_count* specifies the maximum number of packets to capture before returning, and *limit_time* specifies the maximum length of time to wait before returning. The *userid*, *inst*, and *sync* parameters are documented above. This method will return a :class:`ScamperSniff` object if *sync* is ``True``, otherwise it will return a :class:`ScamperTask` representing the scheduled measurement. :class:`ScamperInst` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperInst :class:`ScamperCtrl` provides :class:`ScamperInst` objects to allow instances to be identified and managed. The class implements methods that allow :class:`ScamperInst` objects to be sorted and hashed. .. attribute:: name a string that identifies the instance in some way. .. attribute:: taskc the number of tasks that have been issued but have not yet returned measurement results. .. method:: done() signal that there are no further measurements to come on this :class:`ScamperInst`. This allows the managing :class:`ScamperCtrl` to signal 'end-of-file' when the :class:`ScamperInst` has returned the last measurement result via the *eofcb* callback provided to the :class:`ScamperCtrl` constructor, and allows :meth:`~scamper.ScamperCtrl.is_done` to return ``True`` when this is the last :class:`ScamperInst` managed by the :class:`ScamperCtrl` and it has no further measurement results to return. :class:`ScamperTask` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTask class:`ScamperCtrl` provides :class:`ScamperTask` objects to allow measurements that the caller has scheduled to be halted, if the user does not want the measurement to continue. The class also implements methods that allow :class:`ScamperTask` objects to be sorted and hashed. .. method:: halt() halt the measurement underway. If the measurement was actually started by a scamper instance, then the program will receive the measurement object in its current state. :exc:`ScamperInstError` ^^^^^^^^^^^^^^^^^^^^^^^^^ .. exception:: ScamperInstError Raised when a scamper process rejects a measurement request because either the measurement is unsupported, or the parameters are invalid. The exception will report the raw error message that scamper sent. .. attribute:: inst The :class:`ScamperInst` on which the scamper error message was received. Class for Reading Files ~~~~~~~~~~~~~~~~~~~~~~~ :class:`ScamperFile` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperFile(filename, mode='r', kind=None, filter_types=None) A :class:`ScamperFile` can be used to read and write measurement results collected by scamper. The constructor takes the following parameters, the first of which is mandatory; the remainder are optional named parameters. The *filename* parameter is a string that identifies the name of the file to open. The *mode* parameter is a string ('r' or 'w') identifying whether the file is to be opened read or write. The *kind* parameter is a string specifying the type of the file to open, if opened for writing, and can be one of: warts, warts.gz, warts.bz2, warts.xz, json, or text. The *filter_types* parameter is a list containing the types of the objects to return when reading. By default, a file opened for reading returns all types of objects. The class implements an iterator interface, which a caller can use to read objects out of the file. .. code-block:: file = ScamperFile("foo.warts", filter_types=[ScamperPing]) for ping in file: print(f"{ping.dst}") .. attribute:: filetype a string reporting the type of file opened for reading. The string will contain either 'warts' or 'arts'. .. method:: close() close the file. .. attribute:: filename a string reporting the name of the file originally specified to the constructor. .. method:: filter_types(*types) specify the types of objects to return when reading the file. You can also specify the types of objects to return when constructing the :class:`ScamperFile` object by passing the list of objects to the *filter_types* constructor parameter. This will save you writing code. .. method:: read() read the next object from the file, if the file was opened for reading. .. method:: write(obj) write the object to a :class:`ScamperFile` object to the file, if the file was opened for writing. .. method:: is_write() returns ``True`` if the file was opened for writing. .. method:: is_read() returns ``True`` if the file was opened for reading. Scamper Meta-Objects ~~~~~~~~~~~~~~~~~~~~ :class:`ScamperAddr` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperAddr(addr) Scamper interally stores addresses with its own format, and the :class:`ScamperAddr` class provides an interface to that format. When a scamper measurement object includes an address, it does so with a :class:`ScamperAddr` object. The :class:`ScamperAddr` constructor allows a program to create its own :class:`ScamperAddr` objects from a :obj:`str` or :obj:`bytes` representation of the address. The :class:`ScamperAddr` class implements methods for rendering string representations of the address, sorting, and hashing. .. code-block:: # create an IPv4 address from a string addr = ScamperAddr('192.0.2.1') # create the same IPv4 address using a bytes object addr = ScamperAddr(b'\xc0\x00\x02\x01') # create an IPv6 address using a bytes object addr = ScamperAddr(b'\x20\x01\x0d\xb8\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01') # compare the last address with a string representation of the address if addr == '2001:db8::1': print('this is a documentation address') .. attribute:: packed a Python :obj:`bytes` object containing the address .. method:: is_linklocal() returns ``True`` if the address is in the IPv4 or IPv6 ranges for link-local addresses. .. method:: is_rfc1918() returns ``True`` if the address is in the IPv4 RFC-1918 (private) address ranges. .. method:: is_unicast() returns ``True`` if the address is in the IPv6 unicast prefix. .. method:: is_6to4() returns ``True`` if the address is in the IPv6 6to4 prefix. .. method:: is_reserved() returns ``True`` if the address is in one of the published reserved prefixes. .. method:: is_ipv4() returns ``True`` if the address is an IPv4 address .. method:: is_ipv6() returns ``True`` if the address is an IPv6 address :class:`ScamperList` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperList Scamper appends two metadata objects to each measurement (:class:`ScamperList` and :class:`ScamperCycle`). This class implements methods that allow :class:`ScamperList` objects to be sorted. .. attribute:: id A numeric value assigned to the list. .. attribute:: name A string containing an identifying name of the list. .. attribute:: descr A string with optional metadata attached to the list. .. attribute:: monitor A string with the name of the vantage point that used the list. :class:`ScamperCycle` ^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperCycle Scamper appends two metadata objects to each measurement (:class:`ScamperCycle` and :class:`ScamperList`). This class implements methods that allow :class:`ScamperCycle` objects to be sorted. .. attribute:: id A numeric value assigned to the cycle. .. attribute:: start The start time of the cycle, expressed as a :class:`~datetime.datetime`. .. attribute:: stop The stop time of the cycle, expressed as a :class:`~datetime.datetime`. .. attribute:: hostname The hostname of the :class:`ScamperInst` at the start of the cycle, expressed as a string. :class:`ScamperIcmpExt` ^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperIcmpExt Scamper records ICMP extension data across different measurement types in :class:`ScamperIcmpExt` objects. The most common type of ICMP extension is the MPLS extension, and this class provides methods to interact with that class of ICMP extension. This class implements methods that allow :class:`ScamperIcmpExt` objects to be sorted. .. method:: is_mpls() returns ``True`` if the ICMP extension contains MPLS information. .. attribute:: mpls_count returns the number of MPLS label stack entries in the extension. .. method:: mpls_label(i) returns the label in the label stack entry at offset *i*. .. method:: mpls_ttl(i) returns the TTL in the label stack entry at offset *i*. .. method:: mpls_exp(i) returns the EXP bits in the label stack entry at offset *i*. .. method:: mpls_s(i) returns the bottom-of-stack (S) bit in the label stack entry at offset *i*. Traceroute ~~~~~~~~~~ :class:`ScamperTrace` ^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTrace This class provides information about a traceroute measurement from scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide traceroute measurement objects. The basic properties of the measurement are stored in a :class:`ScamperTrace` object, while the properties of individual responses are stored in :class:`ScamperTraceHop` objects. The following attributes and methods report parameters provided to the traceroute. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: src a :class:`ScamperAddr` containing the source address used in this measurement. .. attribute:: dst a :class:`ScamperAddr` containing the destination address used in this measurement. .. attribute:: rtr a :class:`ScamperAddr` containing the IP address of the router used in this measurement, if the default router was not used. .. attribute:: wait_timeout a :class:`~datetime.timedelta` containing the length of time to wait before declaring a probe lost. .. attribute:: wait_probe a :class:`~datetime.timedelta` containing the length of time to wait between sending probes. .. attribute:: attempts the maximum number of probes sent per hop. .. attribute:: hoplimit the maximum distance (IP TTL) to probe in the traceroute before stopping. .. attribute:: squeries the number of consecutive hops that could have had an outstanding response before pausing for a response. .. attribute:: gaplimit the maximum number of consecutive unresponsive hops that were allowed before stopping. .. attribute:: firsthop the TTL of the first hop probed in the traceroute. .. attribute:: tos the IP type-of-service byte set in the traceroute probes. .. attribute:: confidence an integer value (95 or 99) that controlled the number of probes sent per hop before deciding that all addresses had been observed at the specified confidence level. .. attribute:: probe_size the size of probes sent. .. attribute:: payload the payload included in the probes, as a byte array. .. attribute:: probe_sport the (base) source port used in the measurement, if the measurement used TCP or UDP probes. returns ``None`` if the measurement did not use TCP or UDP probes. .. attribute:: probe_dport the (base) destination port used in the measurement, if the measurement used TCP or UDP probes. returns ``None`` if the measurement did not use TCP or UDP probes. .. attribute:: probe_icmp_sum the ICMP checksum value used in the measurement, if the measurement used ICMP probes. returns ``None`` if the measurement did not use ICMP probes. .. attribute:: offset the value used in the IP fragmentation offset header. .. method:: is_udp() returns ``True`` if the method used UDP probes. .. method:: is_tcp() returns ``True`` if the method used TCP probes. .. method:: is_icmp() returns ``True`` if the method used ICMP probes. The following attributes and methods report data collected in the traceroute. .. attribute:: hop_count how many hops were probed in the path before stopping. .. method:: hops() returns an iterator that provides the first response obtained for each responsive hop. .. code-block:: for h in trace.hops(): print(f"{h}") .. method:: hop(i) returns a :class:`ScamperTraceHop` for the first response obtained for a probe at index *i* in the path, where *i* >= 0 and *i* is less than :attr:`~scamper.ScamperTrace.hop_count`. If there was no response, this method returns ``None``. .. attribute:: probe_count the number of probes sent for this traceroute .. attribute:: pmtud if the traceroute did Path MTU discovery, a :class:`ScamperTracePmtud` object with the parameters and results of that measurement. .. method:: is_stop_noreason() ``True`` if there is no recorded stop reason for the traceroute. .. method:: is_stop_completed() ``True`` if the traceroute reached the destination. .. method:: is_stop_unreach() ``True`` if the traceroute stopped because it received an ICMP destination unreachable message. .. method:: is_stop_icmp() ``True`` if the traceroute stopped because it received an ICMP message that was not a destination unreachable message. .. method:: is_stop_loop() ``True`` if the traceroute stopped because it encountered a loop. .. method:: is_stop_gaplimit() ``True`` if the traceroute stopped because it did not obtain a reply for :attr:`scamper.ScamperTrace.gaplimit` hops. .. method:: is_stop_error() ``True`` if scamper encountered an operating system error while conducting the traceroute. .. method:: is_stop_hoplimit() ``True`` if the traceroute stopped because it reached the maximum distance into the network that it could probe, as defined by :attr:`scamper.ScamperTrace.hoplimit`. .. method:: is_stop_gss() ``True`` if the traceroute stopped because it observed address in the global stop set. .. method:: is_stop_halted() ``True`` if the traceroute was halted before it could complete. :class:`ScamperTraceHop` ^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTraceHop This class provides information about a response to a traceroute probe. It provides a method to render the :class:`ScamperTraceHop` in a string format similar to regular traceroute output. .. attribute:: src a :class:`ScamperAddr` containing the IP address that replied to a probe. .. attribute:: name a string containing the name in a DNS PTR record that was looked up, if scamper attempted to resolve a PTR for the IP address. .. attribute:: tx a :class:`~datetime.datetime` for when the probe was sent, or ``None`` if scamper did not record a timestamp. .. attribute:: rtt a :class:`~datetime.timedelta` containing the round-trip-time for this response. .. attribute:: attempt the attempt number for the probe's TTL. The first attempt has a value of 1. .. attribute:: probe_ttl the TTL set in the probe packet. .. attribute:: probe_size the size of the probe packet. .. attribute:: reply_ttl the TTL value in the IP header of the response, if known. if unknown, then ``None``. .. attribute:: reply_tos the TOS value in the IP header of the response, if known. if unknown, then ``None``. .. attribute:: icmp_type the ICMP type value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: icmp_code the ICMP code value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: reply_size the size of the response, if known. if unknown, then ``None``. .. attribute:: reply_ipid the IPID value in the IP header of the response, if known. if unknown, then ``None``. .. method:: is_tcp() ``True`` if the response packet was a TCP packet. .. method:: is_icmp() ``True`` if the response packet was an ICMP packet. .. method:: is_icmp_q() ``True`` if the response contains an ICMP quotation. .. method:: is_icmp_unreach_port() ``True`` if the response was an ICMP port unreachable. .. method:: is_icmp_echo_reply() ``True`` if the response was an ICMP echo reply. .. method:: is_icmp_ttl_exp() ``True`` if the response was an ICMP TTL expired (time exceeded) message. .. method:: is_icmp_ptb() ``True`` if the response was an ICMP packet too big (fragmentation needed) message. .. attribute:: icmp_nhmtu the next-hop MTU value encoded in the response, if the response was an ICMP packet too big message. .. attribute:: icmp_q_ttl the TTL value in the quoted IP packet, if the response quoted an IP packet. .. attribute:: icmp_q_tos the TOS value in the quoted IP packet, if the response quoted an IP packet. .. attribute:: icmp_q_ipl the IP length value in the quoted IP packet, if the response quoted an IP packet. .. attribute:: tcp_flags the TCP flags contained in a TCP response, if the response was a TCP packet. .. attribute:: icmpext an ICMP extension structure, if the ICMP response included an extension. :class:`ScamperTracePmtud` ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTracePmtud This class provides information about the PMTUD process within a traceroute, if the traceroute included a PMTUD process. .. attribute:: path_mtu the end-to-end path MTU value inferred. .. attribute:: if_mtu the MTU value of the interface used to send the probes. .. attribute:: out_mtu the MTU value to the first hop, which could be different to the interface MTU if the interface has an MTU-mismatch with its network. Ping ~~~~ :class:`ScamperPing` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperPing This class provides information about a ping measurement from scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide ping measurement objects. The basic properties of the measurement are stored in a :class:`ScamperPing` object, while the properties of individual responses are stored in :class:`ScamperPingReply` objects. .. code-block:: print("ping from %s to %s" % (ping.src, ping.dst)) for i in range(ping.probe_count): r = ping.reply(i) if r is None: print("no reply for attempt %d" % (i+1)) else: print("reply from %s, attempt %d" % (i+1)) To iterate over all probes with responses, use the iterator. .. code-block:: print("ping from %s to %s" % (ping.src, ping.dst)) for r in ping: print("reply from %s, attempt %d" % (r.src, r.attempt)) The following attributes and methods report parameters provided to the ping measurement. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: src a :class:`ScamperAddr` containing the source address used in this measurement. .. attribute:: dst a :class:`ScamperAddr` containing the destination address used in this measurement. .. attribute:: rtr a :class:`ScamperAddr` containing the IP address of the router used in this measurement, if the default router was not used. .. attribute:: wait_timeout a :class:`~datetime.timedelta` containing the length of time to wait before declaring a probe lost. .. attribute:: wait_probe a :class:`~datetime.timedelta` containing the length of time to wait between sending probes. .. attribute:: attempts the maximum number of packets that could have been sent in this measurement. .. attribute:: stop_count the number of responses before the measurement could stop. .. attribute:: payload the payload included in the probes, as a :obj:`bytes` object, if the measurement specified the payload to set. .. attribute:: probe_size the size of probes sent. .. attribute:: probe_ttl the TTL set in the IP header of each probe. .. attribute:: probe_tos the type-of-service value set in the IP header of each probe. .. attribute:: probe_sport the (base) source port used in the measurement, if the measurement used TCP or UDP probes. ``None`` if the measurement did not use TCP or UDP probes. .. attribute:: probe_dport the (base) destination port used in the measurement, if the measurement used TCP or UDP probes. ``None`` if the measurement did not use TCP or UDP probes. .. attribute:: probe_icmp_sum the ICMP checksum value used in the measurement, if the measurement used ICMP probes. ``None`` if the measurement did not use ICMP probes. .. attribute:: probe_tcp_seq the TCP sequence number value used in the probes, if the measurement used tcp-syn probes. .. attribute:: probe_tcp_ack the TCP acknowledgment number value used in the probes, if the measurement used tcp-ack probes. .. attribute:: reply_pmtu the psuedo-MTU value used for this measurement, if it used the too-big-trick. .. method:: is_icmp() returns ``True`` if the method used ICMP probes. .. method:: is_icmp_time() returns ``True`` if the method used ICMP timestamp request packets. .. method:: is_tcp() returns ``True`` if the method used TCP probes. .. method:: is_tcp_ack_sport() returns ``True`` if the method used TCP probes, with only the ACK flag set in the TCP header, and varied the source port with each probe. .. method:: is_udp() returns ``True`` if the method used UDP probes. .. method:: is_vary_sport(self): returns ``True`` if the ping measurement sent TCP or UDP packets where the source port changed for each packet. .. method:: is_vary_dport(self): returns ``True`` if the ping measurement sent TCP or UDP packets where the destination port changed for each packet. The following attributes and methods report data collected in the ping measurement. .. attribute:: probe_count the total number of probes sent. This value will be between :attr:`~scamper.ScamperPing.stop_count` and :attr:`~scamper.ScamperPing.attempts`. .. method:: reply(i) returns a :class:`ScamperPingReply` for the nominated attempt, starting at index *i*, where *i* >= 0 and *i* is less than :attr:`~scamper.ScamperPing.probe_count`. If there was no reply, this method returns ``None``. .. attribute:: nreplies the number of probes for which scamper received at least one reply from the destination. .. attribute:: ndups the number of additional replies that scamper received from the destination. .. attribute:: nloss the number of probes for which scamper did not receive any reply. .. attribute:: nerrs the number of response packets that were not from the destination. .. attribute:: min_rtt the minimum RTT observed in responses from the destination, if scamper received at least one reply. the RTT value is expressed in a :class:`~datetime.timedelta` object. .. attribute:: max_rtt the maximum RTT observed in responses from the destination, if scamper received at least one reply. the RTT value is expressed in a :class:`~datetime.timedelta` object. .. attribute:: avg_rtt the average RTT observed in responses from the destination, if scamper received at least one reply. the RTT value is expressed in a :class:`~datetime.timedelta` object. .. attribute:: stddev_rtt the standard deviation for the RTTs observed in responses from the destination, if scamper received at least one reply. the RTT value is expressed in a :class:`~datetime.timedelta` object. :class:`ScamperPingReply` ^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperPingReply This class provides information about a response to a ping probe. It provides a method to render the :class:`ScamperPingReply` in a string format similar to regular ping output. Note that :class:`ScamperPing` stores all responses received to a given probe, even if they are not from the target. For this reason, you should call :meth:`is_from_target` before assuming the reply is from the target. .. method:: src() a :class:`ScamperAddr` containing the IP address that replied to a probe. .. method:: is_from_target() ``True`` if the reply came from the target, i.e., the source address of the response is the same as the destination address of the probe, or if the probe was a UDP probe and the response is an ICMP port unreachable. .. attribute:: tx a :class:`~datetime.datetime` for when the probe was sent, or ``None`` if scamper did not record a timestamp. .. attribute:: rtt a :class:`~datetime.timedelta` containing the round-trip-time for this response. .. attribute:: rx a :class:`~datetime.datetime` for when the response was received. This value is computed by adding :attr:`rtt` to :attr:`tx`. If scamper did not record :attr:`tx`, then :attr:`rx` will be ``None``. .. attribute:: attempt the attempt number for this probe. The first attempt has a value of 1. .. attribute:: probe_ipid the IPID value set for this probe. .. attribute:: reply_ipid the IPID value in the IP header of the response, if known. if unknown, then ``None``. .. attribute:: reply_proto the IP protocol number for this reply (TCP, UDP, ICMP) .. attribute:: reply_ttl the TTL value in the IP header of the response, if known. if unknown, then ``None``. .. attribute:: reply_size the size of the response. .. attribute:: icmp_type the ICMP type value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: icmp_code the ICMP code value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: tcp_flags the TCP flags contained in a TCP response, if the response was a TCP packet. .. attribute:: ifname the name of the interface that received the response, if available. .. method:: is_icmp() ``True`` if the response packet was an ICMP packet. .. method:: is_tcp() ``True`` if the response packet was a TCP packet. .. method:: is_udp() ``True`` if the response packet was a UDP packet. .. method:: is_icmp_echo_reply() ``True`` if the response was an ICMP echo reply. .. method:: is_icmp_unreach() ``True`` if the response was an ICMP destination unreachable. .. method:: is_icmp_unreach_port() ``True`` if the response was an ICMP port unreachable. .. method:: is_icmp_ttl_exp() ``True`` if the response was an ICMP TTL expired (time exceeded) message. .. method:: is_icmp_tsreply() ``True`` if the response was an ICMP timestamp reply. MDA Traceroute ~~~~~~~~~~~~~~ :class:`ScamperTracelb` ^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTracelb This class provides information about an MDA traceroute (tracelb) measurement collected by scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide tracelb measurement objects. The basic properties of the measurement are stored in a :class:`ScamperTracelb` object. The individual nodes in the graph are stored in :class:`ScamperTracelbNode` objects, and links between these nodes are stored in :class:`ScamperTracelbLink` objects. The :class:`ScamperTracelbProbeset` objects store information about a set of probes sent along a link to solicit responses. The probes that were sent to discover topology are stored in :class:`ScamperTracelbProbe` objects, and responses received are stored in :class:`ScamperTracelbReply` objects. These first attributes and methods report parameters provided to the tracelb measurement. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: src a :class:`ScamperAddr` containing the source address used in this measurement. .. attribute:: dst a :class:`ScamperAddr` containing the destination address used in this measurement. .. attribute:: rtr a :class:`ScamperAddr` containing the IP address of the router used in this measurement, if the default router was not used. .. attribute:: wait_timeout a :class:`~datetime.timedelta` containing the length of time to wait before declaring a probe lost. .. attribute:: wait_probe a :class:`~datetime.timedelta` containing the length of time to wait between sending probes. .. attribute:: attempts the maximum number of attempts per probe. .. attribute:: gaplimit the maximum number of consecutive unresponsive hops that were allowed before stopping. .. attribute:: firsthop the TTL of the first hop probed in the traceroute. .. attribute:: tos the IP type-of-service byte set in the traceroute probes. .. attribute:: confidence an integer value (95 or 99) that controlled the number of probes sent per hop before deciding that all addresses had been observed at the specified confidence level. .. attribute:: probe_size the size of probes sent. .. attribute:: probe_sport the (base) source port used in the measurement, if the measurement used TCP or UDP probes. returns ``None`` if the measurement did not use TCP or UDP probes. .. attribute:: probe_dport the (base) destination port used in the measurement, if the measurement used TCP or UDP probes. returns ``None`` if the measurement did not use TCP or UDP probes. .. attribute:: probe_icmp_id the ICMP ID value used in the measurement, if the measurement used ICMP probes. returns ``None`` if the measurement did not use ICMP probes. .. method:: is_udp() returns ``True`` if the method used UDP probes. .. method:: is_tcp() returns ``True`` if the method used TCP probes. .. method:: is_icmp() returns ``True`` if the method used ICMP probes. The following attributes and methods report data collected in the traceroute. .. attribute:: probe_count the total number of probes sent for this measurement. .. attribute:: node_count the number of unique nodes in the graph. .. method:: nodes() an Iterator to step through recorded nodes. .. method:: node(i) obtain the :class:`ScamperTracelbNode` item at index *i*, starting at zero. .. attribute:: link_count the number of unique links in the graph. .. method:: links() an Iterator to step through recorded links. .. method:: link(i) obtain the :class:`ScamperTracelbLink` item at index *i*, starting at zero. :class:`ScamperTracelbNode` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTracelbNode This class provides information about a node observed in an MDA traceroute graph. .. attribute:: src a :class:`ScamperAddr` containing the IP address for the node. .. attribute:: name a string containing the name in a DNS PTR record that was looked up, if scamper attempted to resolve a PTR for the IP address. .. attribute:: icmp_q_ttl the TTL value in the quoted IP packet for the node, if the response quoted an IP packet. .. attribute:: link_count the number of links from this node. .. method:: link(i) obtain the :class:`ScamperTracelbLink` at index *i* attached to this node. .. method:: links() return an Iterator to step through :class:`ScamperTracelbLink` from this node. :class:`ScamperTracelbLink` ^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTracelbLink This class provides information about a link observed in an MDA traceroute graph. It also provides a str method to render the node as a simple string. .. attribute:: near the :class:`ScamperTracelbNode` at the near side of the link. .. attribute:: far the :class:`ScamperTracelbNode` at the far side of the link. .. attribute:: length the length of the link, in hops. most links in a typical graph will have a length of 1. .. attribute:: probeset(i) obtain a :class:`ScamperTracelbProbeset` for part of a link. :class:`ScamperTracelbProbeset` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTracelbProbeset This class provides information about probes sent along a :class:`ScamperTracelbLink` to solicit responses. It provides an Iterator interface to step through the probes. .. attribute:: probe_count the number of probes in this set .. method:: probe(i) obtain the :class:`ScamperTracelbProbe` at offset *i*. :class:`ScamperTracelbProbe` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTracelbProbe This class provides information about a single probe sent as part of a :class:`ScamperTracelb` measurement. It provides a :obj:`str` interface to obtain a simple string representation. .. attribute:: tx a :class:`~datetime.datetime` for when the probe was sent. .. attribute:: flowid the flowid associated with the probe. .. attribute:: ttl the TTL set in the probe packet. .. attribute:: attempt the attempt number for the probe's TTL. The first attempt has a value of 1. .. attribute:: reply_count the number of replies recorded for this probe. .. method:: reply(i) return the :class:`ScamperTracelbReply` at index *i*, starting at zero. :class:`ScamperTracelbReply` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperTracelbReply This class provides information about a single reply received as part of a :class:`ScamperTracelb` measurement. .. method:: src() a :class:`ScamperAddr` containing the IP address that replied to a probe. .. attribute:: rx a :class:`~datetime.datetime` for when the reply was received. .. attribute:: ipid the IPID value in the IP header of the response, if known. if unknown, then ``None``. .. attribute:: ttl the TTL value in the IP header of the response, if known. if unknown, then ``None``. .. attribute:: icmp_type the ICMP type value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: icmp_code the ICMP code value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: icmp_q_ttl the TTL value in the quoted IP packet, if the response quoted an IP packet. .. attribute:: icmp_q_tos the TOS value in the quoted IP packet, if the response quoted an IP packet. .. attribute:: tcp_flags the TCP flags contained in a TCP response, if the response was a TCP packet. .. attribute:: icmpext an ICMP extension structure, if the ICMP response included an extension. Alias Resolution ~~~~~~~~~~~~~~~~ :class:`ScamperDealias` ^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperDealias This class provides information about an alias resolution measurement conducted by scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide dealias measurement objects. These first attributes and methods report parameters provided to the dealias measurement. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: startat the :class:`~datetime.datetime` when this measurement was scheduled to start, or ``None`` if the measurement was to be started at the first scheduled opportunity. Only valid for MIDAR Discovery probing. .. attribute:: probedef_count the number of :class:`ScamperDealiasProbedef` in this measurement. .. method:: probedef(i) obtain the :class:`ScamperDealiasProbedef` at index *i*. .. method:: probedefs() an Iterator that returns :class:`ScamperDealiasProbedef` objects. .. attribute:: wait_probe a :class:`~datetime.timedelta` containing the length of time to wait between sending probes. .. attribute:: wait_round a :class:`~datetime.timedelta` containing the length of time to wait between rounds. .. attribute:: wait_timeout a :class:`~datetime.timedelta` containing the length of time to wait before declaring a probe lost. .. method:: is_ally() ``True`` if the measurement technique was Ally. .. method:: is_mercator() ``True`` if the measurement technique was Mercator. .. method:: is_prefixscan() ``True`` if the measurement technique was Prefixscan. .. method:: is_radargun() ``True`` if the measurement technique was Radargun. .. method:: is_bump() ``True`` if the measurement technique was Bump. .. method:: is_midarest() ``True`` if the measurement technique was MIDAR-style Estimation. .. method:: is_midardisc() ``True`` if the measurement technique was MIDAR-style Discovery. The following attributes and methods report data collected in the measurement. .. method:: has_aliases() ``True`` if the method has aliases to return. This method will only return ``True`` for Mercator, Ally, and Prefixscan. Other measurement techniques require post-processing. .. method:: aliases() Returns a pair of :class:`ScamperAddr` objects that the measurement technique inferred were aliases. This method will only return alias pairs for Mercator, Ally, and Prefixscan. Other measurement techniques require post-processing. ``None`` if no inferred aliases. .. attribute:: probe_count the total number of probes sent for this measurement. .. method:: probe(i=0) return the :class:`ScamperDealiasProbe` at index *i*, starting at zero. .. method:: probes() an Iterator that returns :class:`ScamperDealiasProbe` objects. :class:`ScamperDealiasProbedef` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperDealiasProbedef(method, src=None, dst=None, ttl=None,\ size=None, sport=None, dport=None, icmp_id=None, icmp_sum=None) The :class:`ScamperDealiasProbedef` constructor allows a program to define a probe method for a :class:`ScamperDealias` measurement via :meth:`~scamper.ScamperCtrl.do_radargun`, :meth:`~scamper.ScamperCtrl.do_midarest`, and :meth:`~scamper.ScamperCtrl.do_midardisc`. Only the *method* parameter, which is a string identifying the name of a probing strategy, is mandatory. *src* and *dst* specify IP addresses to use in the source and destination of probes. *ttl* defines the TTL value to assign to probes, and *size* specifies the size of probes to send. *sport* and *dport* specify the (base) source and destination TCP/UDP ports to use in probes. *icmp_id* and *icmp_sum* specify the ID and checksum values to use in the header of ICMP probes. The following attributes and methods report properties of a :class:`ScamperDealiasProbedef` object. .. attribute:: dst a :class:`ScamperAddr` containing the destination address used in this :class:`ScamperDealiasProbedef`. .. attribute:: src a :class:`ScamperAddr` containing the source address used in this :class:`ScamperDealiasProbedef`. .. attribute:: ttl the TTL value to use in the IP header. .. attribute:: size the size of a probe using this :class:`ScamperDealiasProbedef`. .. attribute:: sport the (base) source port used by probes using this :class:`ScamperDealiasProbedef`, if the definition specifies TCP or UDP probes, otherwise ``None``. .. attribute:: dport the (base) destination port used by probes using this :class:`ScamperDealiasProbedef`, if the definition specifies TCP or UDP probes, otherwise ``None``. .. attribute:: icmp_id the ICMP ID value used by probes using this :class:`ScamperDealiasProbedef`, if the definition specifies ICMP probes, otherwise ``None``. .. attribute:: icmp_sum the ICMP checksum value value used by probes using this :class:`ScamperDealiasProbedef`, if the definition specifies ICMP probes, otherwise ``None``. .. method:: is_udp() returns ``True`` if the definition specifies UDP probes. .. method:: is_tcp() returns ``True`` if the definition specifies TCP probes. .. method:: is_icmp() returns ``True`` if the definition specifies ICMP probes. :class:`ScamperDealiasMidardiscRound` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperDealiasMidardiscRound(start, begin, end) The :class:`ScamperDealiasMidardiscRound` constructor allows a program to define parameters for a round in a MIDAR-style discovery round via :meth:`~scamper.ScamperCtrl.do_midardisc`. All parameters are mandatory. *start* is a :class:`~datetime.timedelta` that represents when the round should start, relative to other rounds in the measurement. The first round should have a zero *start* offset. *begin* specifies the index of the first :class:`ScamperDealiasProbedef` in the probedef set to use, while *end* specifies the last. The following attributes and methods report properties of a :class:`ScamperDealiasMidardiscRound` object. .. attribute:: start a :class:`~datetime.timedelta` of when the roud should start relative to other rounds in the measurement. .. attribute:: begin the begin index into an array of probedefs to use in this round. .. attribute:: end the end index into an array of probedefs to use in this round. :class:`ScamperDealiasProbe` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperDealiasProbe This class provides information about a single probe set as part of an alias resolution measurement. .. attribute:: probedef the :class:`ScamperDealiasProbedef` associated with this probe. .. attribute:: seq the sequence number of this probe in relation to other probes in the measurement. .. attribute:: tx a :class:`~datetime.datetime` for when the probe was sent. .. attribute:: ipid the IPID value set in the probe. .. attribute:: reply_count the number of replies recorded for this probe. .. method:: reply(i) return the :class:`ScamperDealiasReply` at index *i*, starting at zero. .. method:: replies() an Iterator that returns :class:`ScamperDealiasReply` objects. :class:`ScamperDealiasReply` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperDealiasReply This class provides information about a single reply received as part of a :class:`ScamperDealias` measurement. Note that :class:`ScamperDealias` stores all responses received to a given probe, even if they are not the desired response type from the target. For this reason, you should call :meth:`is_from_target` before assuming the reply is from the target. .. method:: src() a :class:`ScamperAddr` containing the IP address that replied to a probe. .. method:: is_from_target() ``True`` if the reply came from the target, i.e., the source address of the response is the same as the destination address of the probe, or if the probe was a UDP probe and the response is an ICMP port unreachable. .. attribute:: rx a :class:`~datetime.datetime` for when the reply was received. .. attribute:: ipid the IPID value in the IP header of the response. .. attribute:: ttl the IP TTL value in the IP header of the response. .. attribute:: size the size of the response. .. attribute:: tcp_flags: the TCP flags contained in a TCP response, if the response was a TCP packet. .. attribute:: icmp_type the ICMP type value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: icmp_code the ICMP code value for the response, if the response was an ICMP response. ``None`` if the response was not an ICMP response. .. attribute:: icmp_q_ttl the TTL value in the quoted IP packet, if the response quoted an IP packet. .. method:: is_tcp() ``True`` if the response packet was a TCP packet. .. method:: is_icmp() ``True`` if the response packet was an ICMP packet. .. method:: is_icmp_ttl_exp() ``True`` if the response was an ICMP TTL expired (time exceeded) message. .. method:: is_icmp_unreach() ``True`` if the response was an ICMP destination unreachable. .. method:: is_icmp_unreach_port() ``True`` if the response was an ICMP port unreachable. DNS Measurement ~~~~~~~~~~~~~~~ :class:`ScamperHost` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperHost This class provides information about a DNS measurement conducted by scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide DNS measurement objects via the :class:`ScamperHost` class. These first attributes and methods report parameters provided to the DNS measurement. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: src a :class:`ScamperAddr` containing the source address used in this measurement. .. attribute:: dst a :class:`ScamperAddr` containing the DNS server queried in this measurement. .. attribute:: qtype_num the query type number used in this measurement. .. attribute:: qtype the query type used in this measurement, as a string. e.g. "A" .. attribute:: qclass the query class used in this measurement, as a string, e.g. "IN" .. attribute:: qname the queried name The following attributes and methods report data collected in the measurement. .. attribute:: rcode the DNS rcode value obtained in the response, if the query obtained a response. .. attribute:: tx a :class:`~datetime.datetime` for when the first query with a response was sent. .. attribute:: rx a :class:`~datetime.datetime` for when the first query with a response was received. .. attribute:: rtt a :class:`~datetime.timedelta` containing the round-trip-time for the first query with a response. .. attribute:: ancount the number of AN resource records from the first query with a response. .. method:: an(i) obtain the :class:`ScamperHostRR` at index *i*, starting at offset zero, in the AN section of the first query with a response. .. method:: ans(rrtypes=None) obtain an Iterator over the :class:`ScamperHostRR` in the AN section of the first query with a response. *rrtypes* is an optional list of RR types, identified by a string (e.g., 'a', 'ptr'), to return. .. method:: ans_addrs() return a list of all :class:`ScamperAddr` from the AN section of the first query with a response. .. method:: ans_nses() return a list of all nameservers from the AN section of the first query with a response. .. method:: ans_txts() return a list of all TXT records from the AN seciton of the first query with a response. .. attribute:: nscount the number of NS resource records from the first query with a response. .. method:: ns(i) obtain the :class:`ScamperHostRR` at index *i*, starting at offset zero, in the NS section of the first query with a response. .. method:: nss(rrtypes=None) obtain an Iterator over the :class:`ScamperHostRR` in the NS section of the first query with a response. *rrtypes* is an optional list of RR types, identified by a string (e.g., 'ns', 'a') to return. .. attribute:: arcount the number of AR resource records from the first query with a response. .. method:: ar(i) obtain the :class:`ScamperHostRR` at index *i*, starting at offset zero, in the AR section of the first query with a response. .. method:: ars(rrtypes=None) obtain an Iterator over the :class:`ScamperHostRR` in the AR section of the first query with a response. *rrtypes* is an optional list of RR types, identified by a string (e.g., 'a', 'aaaa') to return. :class:`ScamperHostRR` ^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperHostRR This class provides information about a DNS resource record from a :class:`ScamperHost` reply. It provides a method to render the :class:`ScamperHostRR` in a string format similar to regular host output. .. attribute:: rclass the numeric class value from the RR. .. attribute:: rtype the numeric type value from the RR. .. attribute:: ttl the TTL value from the RR. .. attribute:: name the name value from the RR. .. attribute:: addr a :class:`ScamperAddr`, if the RR contained an IP address. otherwise, ``None``. .. attribute:: ns a string containing the name server reported in the RR, if the RR reported a name server. otherwise, ``None``. .. attribute:: cname a string containing the canonical name (CNAME), if the RR reported a CNAME. otherwise, ``None``. .. attribute:: ptr a string containing the pointer (PTR) value in the RR, if the RR reported a PTR. otherwise, ``None``. .. attribute:: mx a :class:`ScamperHostMX` containing the information recorded in an MX record, if the RR reported an MX. otherwise, ``None``. .. attribute:: soa a :class:`ScamperHostSOA` containing information recorded in a SOA record, if the RR reported a SOA. otherwise, ``None``. :class:`ScamperHostMX` ^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperHostMX This class provides information about a DNS MX resource record from a :class:`ScamperHost` reply. .. attribute:: pref the preference value encoded in the RR. .. attribute:: exch the exchange string encoded in the RR. :class:`ScamperHostSOA` ^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperHostSOA This class provides information about a DNS SOA resource record from a :class:`ScamperHost` reply. .. attribute:: mname the primary master name server for the zone, as encoded in the RR. .. attribute:: rname the email address of the administrator responsible for the zone, as encoded in the RR. .. attribute:: serial the serial number of the zone, as encoded in the RR. .. attribute:: refresh the time interval, in seconds, before the zone should be refreshed from the master, as encoded in the RR. .. attribute:: retry the time interval, in seconds, that should elapse before a failed refresh should be retried, as encoded in the RR. .. attribute:: expire the upper limit on the time interval, in seconds, that can elapse before the zone is no longer authoritative, as encoded in the RR. .. attribute:: minimum the minimum TTL field that should be exported with any RR from this zone, as encoded in the RR. :class:`ScamperHostTXT` ^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperHostTXT This class provides information about a DNS TXT resource record from a :class:`ScamperHost` reply. It also provides an interator that iterates over the strings in the TXT record. .. attribute:: strc the number of strings in this TXT record. .. method:: str(i) return the string at index *i*, starting at zero. HTTP Measurement ~~~~~~~~~~~~~~~~ :class:`ScamperHttp` ^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperHttp This class provides information about an HTTP exchange conducted by scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide DNS measurement objects. This class provides an iterator over the series of :class:`ScamperHttpBuf` records that comprised the HTTP exchange. These first attributes and methods report parameters provided to the HTTP measurement. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: src a :class:`ScamperAddr` containing the source address used in this measurement. .. attribute:: dst a :class:`ScamperAddr` containing the destination address used in this measurement. .. attribute:: sport the source TCP port that scamper used in the exchange. .. attribute:: dport the destination TCP port that scamper used in the exchange. .. attribute:: url the URL for this exchange. The following attributes and methods report data collected in the HTTP exchange. .. attribute:: status_code the status code returned by the server, if the server responded. Otherwise, ``None``. .. attribute:: response a :obj:`bytes` object containing the response payload, if the server responded. Otherwise, ``None``. The response payload does not include the HTTP reader. .. attribute:: response_hdr the HTTP header from the server, as a single string, if the server responded. Otherwise, ``None``. .. attribute:: response_hdrs the HTTP header from the server, stored in a dictionary that maps field names to field values. the field names and values are stored in lower case. if the server did not respond, the returned dictionary will be empty. .. method:: response_hdr_byname(name) obtain the value of a specific header field, identified in the *name* parameter, sent by the server. the value is reported in the same case it was received. if the caller will fetch multiple response headers, it is more efficient to use the dictionary provided by :attr:`response_hdrs`. if the header field does not exist, ``None``. .. attribute:: transmit_hdr the HTTP header that scamper sent to the server, as a single string. .. attribute:: transmit_hdrs the HTTP header that scamper sent to the server, stored in a dictionary that maps field names to field values. the field names and values are stored in lower case. .. method:: transmit_hdr_byname(name) obtain the value of a specific header field, identified in the *name* parameter, sent by scamper to the server. the value is reported in the same case it was transmitted. if the caller will fetch multiple transmit headers, it is more efficient to use the dictionary provided by :attr:`transmit_hdrs`. if the header field does not exist, ``None``. :class:`ScamperHttpBuf` ^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperHttpBuf This class provides information about a single chunk of data transmitted or received by scamper during an HTTP measurement. .. attribute:: timestamp a :class:`~datetime.datetime` reporting when the chunk was transmitted or received. .. attribute:: payload a :obj:`bytes` object containing the payload for this chunk. .. method:: is_tx() ``True`` if this chunk was transmitted by scamper to the server. .. method:: is_rx() ``True`` if this chunk was received by scamper from the server. .. method:: is_tls() ``True`` if this chunk was part of a TLS handshake with the server. .. method:: is_hdr() ``True`` if this chunk is part of an HTTP header, from either scamper or the server. .. method:: is_data() ``True`` if this chunk is part of the payload sent by the server. UDP Probes ~~~~~~~~~~ :class:`ScamperUdpprobe` ^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperUdpprobe This class provides information about a UDP probe sent by scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide UDP probe measurement objects via the :class:`ScamperUdpprobe` class. This class provides an Iterator over one or more :class:`ScamperUdpprobeProbe` records. .. code-block:: for p in udpprobe: print(f"{p.tx} {p.sport}") for r in p: print(f"{p.rx} {len(r.payload)}") These first attributes and methods report parameters provided to the UDP probe measurement. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: src a :class:`ScamperAddr` containing the source address used in this measurement. .. attribute:: dst a :class:`ScamperAddr` containing the destination address used in this measurement. .. attribute:: sport the source TCP port that was provided to this measurement. .. attribute:: dport the destination TCP port that scamper used in the exchange. .. attribute:: attempts the maximum number of packets that could have been sent in this measurement. .. attribute:: stop_count the number of responses before the measurement could stop. .. attribute:: wait_probe a :class:`~datetime.timedelta` containing the length of time to wait between sending probes. .. attribute:: wait_timeout a :class:`~datetime.timedelta` containing the length of time to wait before declaring a probe lost. .. attribute:: payload a :obj:`bytes` object containing the UDP payload sent by scamper. The following attributes and methods report data collected in the measurement. .. attribute:: probe_sent the number of probes sent in this measurement .. method:: probe(i) return the :class:`ScamperUdpprobeProbe` at index *i*, starting at zero. .. method:: replies() return an Iterator that contains the replies obtained during this measurement. Each object is a :class:`ScamperUdpprobeReply`. :class:`ScamperUdpprobeProbe` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperUdpprobeProbe This class provides information about a single probe made in a :class:`ScamperUdpprobe` measurement. .. attribute:: tx a :class:`~datetime.datetime` for when the probe was sent, or ``None`` if scamper did not record a timestamp. .. attribute:: sport the source TCP port that scamper used in the exchange. .. attribute:: reply_count the number of replies recorded for this probe. .. method:: reply(i) return the :class:`ScamperUdpprobeReply` at index *i*, starting at zero. :class:`ScamperUdpprobeReply` ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperUdpprobeReply This class provides information about a response to a UDP probe sent by scamper. .. attribute:: rx a :class:`~datetime.datetime` for when the reply was received. .. attribute:: payload a :obj:`bytes` object containing the UDP payload received by scamper. Packet Capture ~~~~~~~~~~~~~~ :class:`ScamperSniff` ^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperSniff This class provides information about a packet capture collected by scamper. Both :class:`ScamperCtrl` and :class:`ScamperFile` objects provide packet capture measurement objects via :class:`ScamperSniff`. The class provides an Iterator that returns all captured packets in :class:`ScamperSniffPkt` objects. .. code-block:: for p in sniff: print(f"{p.rx} {len(p.data)}") These first attributes and methods report parameters provided to the packet capture measurement. .. attribute:: inst the :class:`ScamperInst` associated with this measurement, when the measurement is returned by a :class:`ScamperCtrl` object. .. attribute:: list the :class:`ScamperList` associated with this measurement. .. attribute:: cycle the :class:`ScamperCycle` associated with this measurement. .. attribute:: userid the userid parameter supplied to the measurement (an unsigned 32-bit integer) .. attribute:: start the :class:`~datetime.datetime` when this measurement started. .. attribute:: src a :class:`ScamperAddr` containing the source address of the interface that was opened for packet capture. .. attribute:: limit_pkt_count the maximum number of packets that this measurement would have waited for before finishing. .. attribute:: limit_time a :class:`~datetime.timedelta` reporting the maximum length of time that the measurement would have waited for before finishing. .. attribute:: icmp_id the ICMP ID value of packets to capture. The following attributes and methods report data collected in the measurement. .. attribute:: finish the :class:`~datetime.datetime` when this measurement finished. .. attribute:: pkt_count the number of packets captured .. method:: pkt(i) the :class:`ScamperSniffPkt` at index *i* in the captured packets, starting at index zero. :class:`ScamperSniffPkt` ^^^^^^^^^^^^^^^^^^^^^^^^ .. class:: ScamperSniffPkt This class provides information about a packet captured by scamper. .. attribute:: rx a :class:`~datetime.datetime` reporting when the packet was captured. .. attribute:: data the contents of the packet, from the IP layer onwards.