• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2015 PLUMgrid
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15from __future__ import print_function
16import atexit
17import ctypes as ct
18import fcntl
19import json
20import os
21import re
22import struct
23import errno
24import sys
25basestring = (unicode if sys.version_info[0] < 3 else str)
26
27from .libbcc import lib, bcc_symbol, bcc_symbol_option, _SYM_CB_TYPE
28from .table import Table, PerfEventArray
29from .perf import Perf
30from .utils import get_online_cpus, printb, _assert_is_bytes, ArgString
31from .version import __version__
32
33_probe_limit = 1000
34_num_open_probes = 0
35
36# for tests
37def _get_num_open_probes():
38    global _num_open_probes
39    return _num_open_probes
40
41TRACEFS = "/sys/kernel/debug/tracing"
42
43# Debug flags
44
45# Debug output compiled LLVM IR.
46DEBUG_LLVM_IR = 0x1
47# Debug output loaded BPF bytecode and register state on branches.
48DEBUG_BPF = 0x2
49# Debug output pre-processor result.
50DEBUG_PREPROCESSOR = 0x4
51# Debug output ASM instructions embedded with source.
52DEBUG_SOURCE = 0x8
53#Debug output register state on all instructions in addition to DEBUG_BPF.
54DEBUG_BPF_REGISTER_STATE = 0x10
55
56class SymbolCache(object):
57    def __init__(self, pid):
58        self.cache = lib.bcc_symcache_new(
59                pid, ct.cast(None, ct.POINTER(bcc_symbol_option)))
60
61    def resolve(self, addr, demangle):
62        """
63        Return a tuple of the symbol (function), its offset from the beginning
64        of the function, and the module in which it lies. For example:
65            ("start_thread", 0x202, "/usr/lib/.../libpthread-2.24.so")
66        If the symbol cannot be found but we know which module it is in,
67        return the module name and the offset from the beginning of the
68        module. If we don't even know the module, return the absolute
69        address as the offset.
70        """
71        sym = bcc_symbol()
72        if demangle:
73            res = lib.bcc_symcache_resolve(self.cache, addr, ct.byref(sym))
74        else:
75            res = lib.bcc_symcache_resolve_no_demangle(self.cache, addr,
76                                                       ct.byref(sym))
77        if res < 0:
78            if sym.module and sym.offset:
79                return (None, sym.offset,
80                        ct.cast(sym.module, ct.c_char_p).value)
81            return (None, addr, None)
82        if demangle:
83            name_res = sym.demangle_name
84            lib.bcc_symbol_free_demangle_name(ct.byref(sym))
85        else:
86            name_res = sym.name
87        return (name_res, sym.offset, ct.cast(sym.module, ct.c_char_p).value)
88
89    def resolve_name(self, module, name):
90        module = _assert_is_bytes(module)
91        name = _assert_is_bytes(name)
92        addr = ct.c_ulonglong()
93        if lib.bcc_symcache_resolve_name(self.cache, module, name,
94                ct.byref(addr)) < 0:
95            return -1
96        return addr.value
97
98class PerfType:
99    # From perf_type_id in uapi/linux/perf_event.h
100    HARDWARE = 0
101    SOFTWARE = 1
102
103class PerfHWConfig:
104    # From perf_hw_id in uapi/linux/perf_event.h
105    CPU_CYCLES = 0
106    INSTRUCTIONS = 1
107    CACHE_REFERENCES = 2
108    CACHE_MISSES = 3
109    BRANCH_INSTRUCTIONS = 4
110    BRANCH_MISSES = 5
111    BUS_CYCLES = 6
112    STALLED_CYCLES_FRONTEND = 7
113    STALLED_CYCLES_BACKEND = 8
114    REF_CPU_CYCLES = 9
115
116class PerfSWConfig:
117    # From perf_sw_id in uapi/linux/perf_event.h
118    CPU_CLOCK = 0
119    TASK_CLOCK = 1
120    PAGE_FAULTS = 2
121    CONTEXT_SWITCHES = 3
122    CPU_MIGRATIONS = 4
123    PAGE_FAULTS_MIN = 5
124    PAGE_FAULTS_MAJ = 6
125    ALIGNMENT_FAULTS = 7
126    EMULATION_FAULTS = 8
127    DUMMY = 9
128    BPF_OUTPUT = 10
129
130class BPF(object):
131    # From bpf_prog_type in uapi/linux/bpf.h
132    SOCKET_FILTER = 1
133    KPROBE = 2
134    SCHED_CLS = 3
135    SCHED_ACT = 4
136    TRACEPOINT = 5
137    XDP = 6
138    PERF_EVENT = 7
139    CGROUP_SKB = 8
140    CGROUP_SOCK = 9
141    LWT_IN = 10
142    LWT_OUT = 11
143    LWT_XMIT = 12
144    SOCK_OPS = 13
145    SK_SKB = 14
146    CGROUP_DEVICE = 15
147    SK_MSG = 16
148    RAW_TRACEPOINT = 17
149    CGROUP_SOCK_ADDR = 18
150
151    # from xdp_action uapi/linux/bpf.h
152    XDP_ABORTED = 0
153    XDP_DROP = 1
154    XDP_PASS = 2
155    XDP_TX = 3
156    XDP_REDIRECT = 4
157
158    _probe_repl = re.compile(b"[^a-zA-Z0-9_]")
159    _sym_caches = {}
160
161    _auto_includes = {
162        "linux/time.h": ["time"],
163        "linux/fs.h": ["fs", "file"],
164        "linux/blkdev.h": ["bio", "request"],
165        "linux/slab.h": ["alloc"],
166        "linux/netdevice.h": ["sk_buff", "net_device"]
167    }
168
169    _syscall_prefixes = [
170        b"sys_",
171        b"__x64_sys_",
172        b"__x32_compat_sys_",
173        b"__ia32_compat_sys_",
174    ]
175
176    # BPF timestamps come from the monotonic clock. To be able to filter
177    # and compare them from Python, we need to invoke clock_gettime.
178    # Adapted from http://stackoverflow.com/a/1205762
179    CLOCK_MONOTONIC = 1         # see <linux/time.h>
180
181    class timespec(ct.Structure):
182        _fields_ = [('tv_sec', ct.c_long), ('tv_nsec', ct.c_long)]
183
184    _librt = ct.CDLL('librt.so.1', use_errno=True)
185    _clock_gettime = _librt.clock_gettime
186    _clock_gettime.argtypes = [ct.c_int, ct.POINTER(timespec)]
187
188    @classmethod
189    def monotonic_time(cls):
190        """monotonic_time()
191        Returns the system monotonic time from clock_gettime, using the
192        CLOCK_MONOTONIC constant. The time returned is in nanoseconds.
193        """
194        t = cls.timespec()
195        if cls._clock_gettime(cls.CLOCK_MONOTONIC, ct.byref(t)) != 0:
196            errno = ct.get_errno()
197            raise OSError(errno, os.strerror(errno))
198        return t.tv_sec * 1e9 + t.tv_nsec
199
200    @classmethod
201    def generate_auto_includes(cls, program_words):
202        """
203        Generates #include statements automatically based on a set of
204        recognized types such as sk_buff and bio. The input is all the words
205        that appear in the BPF program, and the output is a (possibly empty)
206        string of #include statements, such as "#include <linux/fs.h>".
207        """
208        headers = ""
209        for header, keywords in cls._auto_includes.items():
210            for keyword in keywords:
211                for word in program_words:
212                    if keyword in word and header not in headers:
213                        headers += "#include <%s>\n" % header
214        return headers
215
216    # defined for compatibility reasons, to be removed
217    Table = Table
218
219    class Function(object):
220        def __init__(self, bpf, name, fd):
221            self.bpf = bpf
222            self.name = name
223            self.fd = fd
224
225    @staticmethod
226    def _find_file(filename):
227        """ If filename is invalid, search in ./ of argv[0] """
228        if filename:
229            if not os.path.isfile(filename):
230                argv0 = ArgString(sys.argv[0])
231                t = b"/".join([os.path.abspath(os.path.dirname(argv0.__str__())), filename])
232                if os.path.isfile(t):
233                    filename = t
234                else:
235                    raise Exception("Could not find file %s" % filename)
236        return filename
237
238    @staticmethod
239    def find_exe(bin_path):
240        """
241        find_exe(bin_path)
242
243        Traverses the PATH environment variable, looking for the first
244        directory that contains an executable file named bin_path, and
245        returns the full path to that file, or None if no such file
246        can be found. This is meant to replace invocations of the
247        "which" shell utility, which doesn't have portable semantics
248        for skipping aliases.
249        """
250        # Source: http://stackoverflow.com/a/377028
251        def is_exe(fpath):
252            return os.path.isfile(fpath) and \
253                os.access(fpath, os.X_OK)
254
255        fpath, fname = os.path.split(bin_path)
256        if fpath:
257            if is_exe(bin_path):
258                return bin_path
259        else:
260            for path in os.environ["PATH"].split(os.pathsep):
261                path = path.strip('"')
262                exe_file = os.path.join(path, bin_path)
263                if is_exe(exe_file):
264                    return exe_file
265        return None
266
267    def __init__(self, src_file=b"", hdr_file=b"", text=None, debug=0,
268            cflags=[], usdt_contexts=[]):
269        """Create a new BPF module with the given source code.
270
271        Note:
272            All fields are marked as optional, but either `src_file` or `text`
273            must be supplied, and not both.
274
275        Args:
276            src_file (Optional[str]): Path to a source file for the module
277            hdr_file (Optional[str]): Path to a helper header file for the `src_file`
278            text (Optional[str]): Contents of a source file for the module
279            debug (Optional[int]): Flags used for debug prints, can be |'d together
280                                   See "Debug flags" for explanation
281        """
282
283        src_file = _assert_is_bytes(src_file)
284        hdr_file = _assert_is_bytes(hdr_file)
285        text = _assert_is_bytes(text)
286
287        self.kprobe_fds = {}
288        self.uprobe_fds = {}
289        self.tracepoint_fds = {}
290        self.raw_tracepoint_fds = {}
291        self.perf_buffers = {}
292        self.open_perf_events = {}
293        self.tracefile = None
294        atexit.register(self.cleanup)
295
296        self.debug = debug
297        self.funcs = {}
298        self.tables = {}
299        self.module = None
300        cflags_array = (ct.c_char_p * len(cflags))()
301        for i, s in enumerate(cflags): cflags_array[i] = bytes(ArgString(s))
302        if text:
303            ctx_array = (ct.c_void_p * len(usdt_contexts))()
304            for i, usdt in enumerate(usdt_contexts):
305                ctx_array[i] = ct.c_void_p(usdt.get_context())
306            usdt_text = lib.bcc_usdt_genargs(ctx_array, len(usdt_contexts))
307            if usdt_text is None:
308                raise Exception("can't generate USDT probe arguments; " +
309                                "possible cause is missing pid when a " +
310                                "probe in a shared object has multiple " +
311                                "locations")
312            text = usdt_text + text
313
314        if text:
315            self.module = lib.bpf_module_create_c_from_string(text,
316                    self.debug, cflags_array, len(cflags_array))
317            if not self.module:
318                raise Exception("Failed to compile BPF text")
319        else:
320            src_file = BPF._find_file(src_file)
321            hdr_file = BPF._find_file(hdr_file)
322            if src_file.endswith(b".b"):
323                self.module = lib.bpf_module_create_b(src_file, hdr_file,
324                        self.debug)
325            else:
326                self.module = lib.bpf_module_create_c(src_file, self.debug,
327                        cflags_array, len(cflags_array))
328            if not self.module:
329                raise Exception("Failed to compile BPF module %s" % src_file)
330
331        for usdt_context in usdt_contexts:
332            usdt_context.attach_uprobes(self)
333
334        # If any "kprobe__" or "tracepoint__" or "raw_tracepoint__"
335        # prefixed functions were defined,
336        # they will be loaded and attached here.
337        self._trace_autoload()
338
339    def load_funcs(self, prog_type=KPROBE):
340        """load_funcs(prog_type=KPROBE)
341
342        Load all functions in this BPF module with the given type.
343        Returns a list of the function handles."""
344
345        fns = []
346        for i in range(0, lib.bpf_num_functions(self.module)):
347            func_name = lib.bpf_function_name(self.module, i)
348            fns.append(self.load_func(func_name, prog_type))
349
350        return fns
351
352    def load_func(self, func_name, prog_type):
353        func_name = _assert_is_bytes(func_name)
354        if func_name in self.funcs:
355            return self.funcs[func_name]
356        if not lib.bpf_function_start(self.module, func_name):
357            raise Exception("Unknown program %s" % func_name)
358        log_level = 0
359        if (self.debug & DEBUG_BPF_REGISTER_STATE):
360            log_level = 2
361        elif (self.debug & DEBUG_BPF):
362            log_level = 1
363        fd = lib.bpf_prog_load(prog_type, func_name,
364                lib.bpf_function_start(self.module, func_name),
365                lib.bpf_function_size(self.module, func_name),
366                lib.bpf_module_license(self.module),
367                lib.bpf_module_kern_version(self.module),
368                log_level, None, 0);
369
370        if fd < 0:
371            atexit.register(self.donothing)
372            if ct.get_errno() == errno.EPERM:
373                raise Exception("Need super-user privileges to run")
374
375            errstr = os.strerror(ct.get_errno())
376            raise Exception("Failed to load BPF program %s: %s" %
377                            (func_name, errstr))
378
379        fn = BPF.Function(self, func_name, fd)
380        self.funcs[func_name] = fn
381
382        return fn
383
384    def dump_func(self, func_name):
385        """
386        Return the eBPF bytecodes for the specified function as a string
387        """
388        func_name = _assert_is_bytes(func_name)
389        if not lib.bpf_function_start(self.module, func_name):
390            raise Exception("Unknown program %s" % func_name)
391
392        start, = lib.bpf_function_start(self.module, func_name),
393        size, = lib.bpf_function_size(self.module, func_name),
394        return ct.string_at(start, size)
395
396    str2ctype = {
397        u"_Bool": ct.c_bool,
398        u"char": ct.c_char,
399        u"wchar_t": ct.c_wchar,
400        u"unsigned char": ct.c_ubyte,
401        u"short": ct.c_short,
402        u"unsigned short": ct.c_ushort,
403        u"int": ct.c_int,
404        u"unsigned int": ct.c_uint,
405        u"long": ct.c_long,
406        u"unsigned long": ct.c_ulong,
407        u"long long": ct.c_longlong,
408        u"unsigned long long": ct.c_ulonglong,
409        u"float": ct.c_float,
410        u"double": ct.c_double,
411        u"long double": ct.c_longdouble,
412        u"__int128": ct.c_int64 * 2,
413        u"unsigned __int128": ct.c_uint64 * 2,
414    }
415    @staticmethod
416    def _decode_table_type(desc):
417        if isinstance(desc, basestring):
418            return BPF.str2ctype[desc]
419        anon = []
420        fields = []
421        for t in desc[1]:
422            if len(t) == 2:
423                fields.append((t[0], BPF._decode_table_type(t[1])))
424            elif len(t) == 3:
425                if isinstance(t[2], list):
426                    fields.append((t[0], BPF._decode_table_type(t[1]) * t[2][0]))
427                elif isinstance(t[2], int):
428                    fields.append((t[0], BPF._decode_table_type(t[1]), t[2]))
429                elif isinstance(t[2], basestring) and (
430                        t[2] == u"union" or t[2] == u"struct" or
431                        t[2] == u"struct_packed"):
432                    name = t[0]
433                    if name == "":
434                        name = "__anon%d" % len(anon)
435                        anon.append(name)
436                    fields.append((name, BPF._decode_table_type(t)))
437                else:
438                    raise Exception("Failed to decode type %s" % str(t))
439            else:
440                raise Exception("Failed to decode type %s" % str(t))
441        base = ct.Structure
442        is_packed = False
443        if len(desc) > 2:
444            if desc[2] == u"union":
445                base = ct.Union
446            elif desc[2] == u"struct":
447                base = ct.Structure
448            elif desc[2] == u"struct_packed":
449                base = ct.Structure
450                is_packed = True
451        if is_packed:
452            cls = type(str(desc[0]), (base,), dict(_anonymous_=anon, _pack_=1,
453                _fields_=fields))
454        else:
455            cls = type(str(desc[0]), (base,), dict(_anonymous_=anon,
456                _fields_=fields))
457        return cls
458
459    def get_table(self, name, keytype=None, leaftype=None, reducer=None):
460        name = _assert_is_bytes(name)
461        map_id = lib.bpf_table_id(self.module, name)
462        map_fd = lib.bpf_table_fd(self.module, name)
463        if map_fd < 0:
464            raise KeyError
465        if not keytype:
466            key_desc = lib.bpf_table_key_desc(self.module, name).decode("utf-8")
467            if not key_desc:
468                raise Exception("Failed to load BPF Table %s key desc" % name)
469            keytype = BPF._decode_table_type(json.loads(key_desc))
470        if not leaftype:
471            leaf_desc = lib.bpf_table_leaf_desc(self.module, name).decode("utf-8")
472            if not leaf_desc:
473                raise Exception("Failed to load BPF Table %s leaf desc" % name)
474            leaftype = BPF._decode_table_type(json.loads(leaf_desc))
475        return Table(self, map_id, map_fd, keytype, leaftype, reducer=reducer)
476
477    def __getitem__(self, key):
478        if key not in self.tables:
479            self.tables[key] = self.get_table(key)
480        return self.tables[key]
481
482    def __setitem__(self, key, leaf):
483        self.tables[key] = leaf
484
485    def __len__(self):
486        return len(self.tables)
487
488    def __delitem__(self, key):
489        del self.tables[key]
490
491    def __iter__(self):
492        return self.tables.__iter__()
493
494    @staticmethod
495    def attach_raw_socket(fn, dev):
496        dev = _assert_is_bytes(dev)
497        if not isinstance(fn, BPF.Function):
498            raise Exception("arg 1 must be of type BPF.Function")
499        sock = lib.bpf_open_raw_sock(dev)
500        if sock < 0:
501            errstr = os.strerror(ct.get_errno())
502            raise Exception("Failed to open raw device %s: %s" % (dev, errstr))
503        res = lib.bpf_attach_socket(sock, fn.fd)
504        if res < 0:
505            errstr = os.strerror(ct.get_errno())
506            raise Exception("Failed to attach BPF to device %s: %s"
507                    % (dev, errstr))
508        fn.sock = sock
509
510    @staticmethod
511    def get_kprobe_functions(event_re):
512        with open("%s/../kprobes/blacklist" % TRACEFS, "rb") as blacklist_f:
513            blacklist = set([line.rstrip().split()[1] for line in blacklist_f])
514        fns = []
515
516        in_init_section = 0
517        with open("/proc/kallsyms", "rb") as avail_file:
518            for line in avail_file:
519                (t, fn) = line.rstrip().split()[1:3]
520                if in_init_section == 0:
521                    if fn == b'__init_begin':
522                        in_init_section = 1
523                        continue
524                elif in_init_section == 1:
525                    if fn == b'__init_end':
526                        in_init_section = 2
527                    continue
528                if (t.lower() in [b't', b'w']) and re.match(event_re, fn) \
529                    and fn not in blacklist:
530                    fns.append(fn)
531        return set(fns)     # Some functions may appear more than once
532
533    def _check_probe_quota(self, num_new_probes):
534        global _num_open_probes
535        if _num_open_probes + num_new_probes > _probe_limit:
536            raise Exception("Number of open probes would exceed global quota")
537
538    def _add_kprobe_fd(self, name, fd):
539        global _num_open_probes
540        self.kprobe_fds[name] = fd
541        _num_open_probes += 1
542
543    def _del_kprobe_fd(self, name):
544        global _num_open_probes
545        del self.kprobe_fds[name]
546        _num_open_probes -= 1
547
548    def _add_uprobe_fd(self, name, fd):
549        global _num_open_probes
550        self.uprobe_fds[name] = fd
551        _num_open_probes += 1
552
553    def _del_uprobe_fd(self, name):
554        global _num_open_probes
555        del self.uprobe_fds[name]
556        _num_open_probes -= 1
557
558    # Find current system's syscall prefix by testing on the BPF syscall.
559    # If no valid value found, will return the first possible value which
560    # would probably lead to error in later API calls.
561    def get_syscall_prefix(self):
562        for prefix in self._syscall_prefixes:
563            if self.ksymname(b"%sbpf" % prefix) != -1:
564                return prefix
565        return self._syscall_prefixes[0]
566
567    # Given a syscall's name, return the full Kernel function name with current
568    # system's syscall prefix. For example, given "clone" the helper would
569    # return "sys_clone" or "__x64_sys_clone".
570    def get_syscall_fnname(self, name):
571        name = _assert_is_bytes(name)
572        return self.get_syscall_prefix() + name
573
574    # Given a Kernel function name that represents a syscall but already has a
575    # prefix included, transform it to current system's prefix. For example,
576    # if "sys_clone" provided, the helper may translate it to "__x64_sys_clone".
577    def fix_syscall_fnname(self, name):
578        name = _assert_is_bytes(name)
579        for prefix in self._syscall_prefixes:
580            if name.startswith(prefix):
581                return self.get_syscall_fnname(name[len(prefix):])
582        return name
583
584    def attach_kprobe(self, event=b"", event_off=0, fn_name=b"", event_re=b""):
585        event = _assert_is_bytes(event)
586        fn_name = _assert_is_bytes(fn_name)
587        event_re = _assert_is_bytes(event_re)
588
589        # allow the caller to glob multiple functions together
590        if event_re:
591            matches = BPF.get_kprobe_functions(event_re)
592            self._check_probe_quota(len(matches))
593            for line in matches:
594                try:
595                    self.attach_kprobe(event=line, fn_name=fn_name)
596                except:
597                    pass
598            return
599
600        self._check_probe_quota(1)
601        fn = self.load_func(fn_name, BPF.KPROBE)
602        ev_name = b"p_" + event.replace(b"+", b"_").replace(b".", b"_")
603        fd = lib.bpf_attach_kprobe(fn.fd, 0, ev_name, event, event_off)
604        if fd < 0:
605            raise Exception("Failed to attach BPF to kprobe")
606        self._add_kprobe_fd(ev_name, fd)
607        return self
608
609    def attach_kretprobe(self, event=b"", fn_name=b"", event_re=b""):
610        event = _assert_is_bytes(event)
611        fn_name = _assert_is_bytes(fn_name)
612        event_re = _assert_is_bytes(event_re)
613
614        # allow the caller to glob multiple functions together
615        if event_re:
616            for line in BPF.get_kprobe_functions(event_re):
617                try:
618                    self.attach_kretprobe(event=line, fn_name=fn_name)
619                except:
620                    pass
621            return
622
623        self._check_probe_quota(1)
624        fn = self.load_func(fn_name, BPF.KPROBE)
625        ev_name = b"r_" + event.replace(b"+", b"_").replace(b".", b"_")
626        fd = lib.bpf_attach_kprobe(fn.fd, 1, ev_name, event, 0)
627        if fd < 0:
628            raise Exception("Failed to attach BPF to kretprobe")
629        self._add_kprobe_fd(ev_name, fd)
630        return self
631
632    def detach_kprobe_event(self, ev_name):
633        if ev_name not in self.kprobe_fds:
634            raise Exception("Kprobe %s is not attached" % event)
635        res = lib.bpf_close_perf_event_fd(self.kprobe_fds[ev_name])
636        if res < 0:
637            raise Exception("Failed to close kprobe FD")
638        res = lib.bpf_detach_kprobe(ev_name)
639        if res < 0:
640            raise Exception("Failed to detach BPF from kprobe")
641        self._del_kprobe_fd(ev_name)
642
643    def detach_kprobe(self, event):
644        event = _assert_is_bytes(event)
645        ev_name = b"p_" + event.replace(b"+", b"_").replace(b".", b"_")
646        self.detach_kprobe_event(ev_name)
647
648    def detach_kretprobe(self, event):
649        event = _assert_is_bytes(event)
650        ev_name = b"r_" + event.replace(b"+", b"_").replace(b".", b"_")
651        self.detach_kprobe_event(ev_name)
652
653    @staticmethod
654    def attach_xdp(dev, fn, flags=0):
655        '''
656            This function attaches a BPF function to a device on the device
657            driver level (XDP)
658        '''
659        dev = _assert_is_bytes(dev)
660        if not isinstance(fn, BPF.Function):
661            raise Exception("arg 1 must be of type BPF.Function")
662        res = lib.bpf_attach_xdp(dev, fn.fd, flags)
663        if res < 0:
664            err_no = ct.get_errno()
665            if err_no == errno.EBADMSG:
666                raise Exception("Internal error while attaching BPF to device,"+
667                    " try increasing the debug level!")
668            else:
669                errstr = os.strerror(err_no)
670                raise Exception("Failed to attach BPF to device %s: %s"
671                            % (dev, errstr))
672
673    @staticmethod
674    def remove_xdp(dev, flags=0):
675        '''
676            This function removes any BPF function from a device on the
677            device driver level (XDP)
678        '''
679        dev = _assert_is_bytes(dev)
680        res = lib.bpf_attach_xdp(dev, -1, flags)
681        if res < 0:
682            errstr = os.strerror(ct.get_errno())
683            raise Exception("Failed to detach BPF from device %s: %s"
684                            % (dev, errstr))
685
686
687
688    @classmethod
689    def _check_path_symbol(cls, module, symname, addr, pid):
690        module = _assert_is_bytes(module)
691        symname = _assert_is_bytes(symname)
692        sym = bcc_symbol()
693        c_pid = 0 if pid == -1 else pid
694        if lib.bcc_resolve_symname(
695            module, symname,
696            addr or 0x0, c_pid,
697            ct.cast(None, ct.POINTER(bcc_symbol_option)),
698            ct.byref(sym),
699        ) < 0:
700            raise Exception("could not determine address of symbol %s" % symname)
701        module_path = ct.cast(sym.module, ct.c_char_p).value
702        lib.bcc_procutils_free(sym.module)
703        return module_path, sym.offset
704
705    @staticmethod
706    def find_library(libname):
707        libname = _assert_is_bytes(libname)
708        res = lib.bcc_procutils_which_so(libname, 0)
709        if not res:
710            return None
711        libpath = ct.cast(res, ct.c_char_p).value
712        lib.bcc_procutils_free(res)
713        return libpath
714
715    @staticmethod
716    def get_tracepoints(tp_re):
717        results = []
718        events_dir = os.path.join(TRACEFS, "events")
719        for category in os.listdir(events_dir):
720            cat_dir = os.path.join(events_dir, category)
721            if not os.path.isdir(cat_dir):
722                continue
723            for event in os.listdir(cat_dir):
724                evt_dir = os.path.join(cat_dir, event)
725                if os.path.isdir(evt_dir):
726                    tp = ("%s:%s" % (category, event))
727                    if re.match(tp_re, tp):
728                        results.append(tp)
729        return results
730
731    @staticmethod
732    def tracepoint_exists(category, event):
733        evt_dir = os.path.join(TRACEFS, "events", category, event)
734        return os.path.isdir(evt_dir)
735
736    def attach_tracepoint(self, tp=b"", tp_re=b"", fn_name=b""):
737        """attach_tracepoint(tp="", tp_re="", fn_name="")
738
739        Run the bpf function denoted by fn_name every time the kernel tracepoint
740        specified by 'tp' is hit. The optional parameters pid, cpu, and group_fd
741        can be used to filter the probe. The tracepoint specification is simply
742        the tracepoint category and the tracepoint name, separated by a colon.
743        For example: sched:sched_switch, syscalls:sys_enter_bind, etc.
744
745        Instead of a tracepoint name, a regular expression can be provided in
746        tp_re. The program will then attach to tracepoints that match the
747        provided regular expression.
748
749        To obtain a list of kernel tracepoints, use the tplist tool or cat the
750        file /sys/kernel/debug/tracing/available_events.
751
752        Examples:
753            BPF(text).attach_tracepoint(tp="sched:sched_switch", fn_name="on_switch")
754            BPF(text).attach_tracepoint(tp_re="sched:.*", fn_name="on_switch")
755        """
756
757        tp = _assert_is_bytes(tp)
758        tp_re = _assert_is_bytes(tp_re)
759        fn_name = _assert_is_bytes(fn_name)
760        if tp_re:
761            for tp in BPF.get_tracepoints(tp_re):
762                self.attach_tracepoint(tp=tp, fn_name=fn_name)
763            return
764
765        fn = self.load_func(fn_name, BPF.TRACEPOINT)
766        (tp_category, tp_name) = tp.split(b':')
767        fd = lib.bpf_attach_tracepoint(fn.fd, tp_category, tp_name)
768        if fd < 0:
769            raise Exception("Failed to attach BPF to tracepoint")
770        self.tracepoint_fds[tp] = fd
771        return self
772
773    def attach_raw_tracepoint(self, tp=b"", fn_name=b""):
774        """attach_raw_tracepoint(self, tp=b"", fn_name=b"")
775
776        Run the bpf function denoted by fn_name every time the kernel tracepoint
777        specified by 'tp' is hit. The bpf function should be loaded as a
778        RAW_TRACEPOINT type. The fn_name is the kernel tracepoint name,
779        e.g., sched_switch, sys_enter_bind, etc.
780
781        Examples:
782            BPF(text).attach_raw_tracepoint(tp="sched_switch", fn_name="on_switch")
783        """
784
785        tp = _assert_is_bytes(tp)
786        if tp in self.raw_tracepoint_fds:
787            raise Exception("Raw tracepoint %s has been attached" % tp)
788
789        fn_name = _assert_is_bytes(fn_name)
790        fn = self.load_func(fn_name, BPF.RAW_TRACEPOINT)
791        fd = lib.bpf_attach_raw_tracepoint(fn.fd, tp)
792        if fd < 0:
793            raise Exception("Failed to attach BPF to raw tracepoint")
794        self.raw_tracepoint_fds[tp] = fd;
795        return self
796
797    def detach_raw_tracepoint(self, tp=b""):
798        """detach_raw_tracepoint(tp="")
799
800        Stop running the bpf function that is attached to the kernel tracepoint
801        specified by 'tp'.
802
803        Example: bpf.detach_raw_tracepoint("sched_switch")
804        """
805
806        tp = _assert_is_bytes(tp)
807        if tp not in self.raw_tracepoint_fds:
808            raise Exception("Raw tracepoint %s is not attached" % tp)
809        os.close(self.raw_tracepoint_fds[tp])
810        del self.raw_tracepoint_fds[tp]
811
812    @staticmethod
813    def support_raw_tracepoint():
814        # kernel symbol "bpf_find_raw_tracepoint" indicates raw_tracepint support
815        if BPF.ksymname("bpf_find_raw_tracepoint") != -1:
816            return True
817        return False
818
819    def detach_tracepoint(self, tp=b""):
820        """detach_tracepoint(tp="")
821
822        Stop running a bpf function that is attached to the kernel tracepoint
823        specified by 'tp'.
824
825        Example: bpf.detach_tracepoint("sched:sched_switch")
826        """
827
828        tp = _assert_is_bytes(tp)
829        if tp not in self.tracepoint_fds:
830            raise Exception("Tracepoint %s is not attached" % tp)
831        res = lib.bpf_close_perf_event_fd(self.tracepoint_fds[tp])
832        if res < 0:
833            raise Exception("Failed to detach BPF from tracepoint")
834        (tp_category, tp_name) = tp.split(b':')
835        res = lib.bpf_detach_tracepoint(tp_category, tp_name)
836        if res < 0:
837            raise Exception("Failed to detach BPF from tracepoint")
838        del self.tracepoint_fds[tp]
839
840    def _attach_perf_event(self, progfd, ev_type, ev_config,
841            sample_period, sample_freq, pid, cpu, group_fd):
842        res = lib.bpf_attach_perf_event(progfd, ev_type, ev_config,
843                sample_period, sample_freq, pid, cpu, group_fd)
844        if res < 0:
845            raise Exception("Failed to attach BPF to perf event")
846        return res
847
848    def attach_perf_event(self, ev_type=-1, ev_config=-1, fn_name=b"",
849            sample_period=0, sample_freq=0, pid=-1, cpu=-1, group_fd=-1):
850        fn_name = _assert_is_bytes(fn_name)
851        fn = self.load_func(fn_name, BPF.PERF_EVENT)
852        res = {}
853        if cpu >= 0:
854            res[cpu] = self._attach_perf_event(fn.fd, ev_type, ev_config,
855                    sample_period, sample_freq, pid, cpu, group_fd)
856        else:
857            for i in get_online_cpus():
858                res[i] = self._attach_perf_event(fn.fd, ev_type, ev_config,
859                        sample_period, sample_freq, pid, i, group_fd)
860        self.open_perf_events[(ev_type, ev_config)] = res
861
862    def detach_perf_event(self, ev_type=-1, ev_config=-1):
863        try:
864            fds = self.open_perf_events[(ev_type, ev_config)]
865        except KeyError:
866            raise Exception("Perf event type {} config {} not attached".format(
867                ev_type, ev_config))
868
869        res = 0
870        for fd in fds.values():
871            res = lib.bpf_close_perf_event_fd(fd) or res
872        if res != 0:
873            raise Exception("Failed to detach BPF from perf event")
874        del self.open_perf_events[(ev_type, ev_config)]
875
876    @staticmethod
877    def get_user_functions(name, sym_re):
878        return set([name for (name, _) in
879                    BPF.get_user_functions_and_addresses(name, sym_re)])
880
881    @staticmethod
882    def get_user_addresses(name, sym_re):
883        """
884        We are returning addresses here instead of symbol names because it
885        turns out that the same name may appear multiple times with different
886        addresses, and the same address may appear multiple times with the same
887        name. We can't attach a uprobe to the same address more than once, so
888        it makes sense to return the unique set of addresses that are mapped to
889        a symbol that matches the provided regular expression.
890        """
891        return set([address for (_, address) in
892                    BPF.get_user_functions_and_addresses(name, sym_re)])
893
894    @staticmethod
895    def get_user_functions_and_addresses(name, sym_re):
896        name = _assert_is_bytes(name)
897        sym_re = _assert_is_bytes(sym_re)
898        addresses = []
899        def sym_cb(sym_name, addr):
900            dname = sym_name
901            if re.match(sym_re, dname):
902                addresses.append((dname, addr))
903            return 0
904
905        res = lib.bcc_foreach_function_symbol(name, _SYM_CB_TYPE(sym_cb))
906        if res < 0:
907            raise Exception("Error %d enumerating symbols in %s" % (res, name))
908        return addresses
909
910    def _get_uprobe_evname(self, prefix, path, addr, pid):
911        if pid == -1:
912            return b"%s_%s_0x%x" % (prefix, self._probe_repl.sub(b"_", path), addr)
913        else:
914            # if pid is valid, put pid in the name, so different pid
915            # can have different event names
916            return b"%s_%s_0x%x_%d" % (prefix, self._probe_repl.sub(b"_", path), addr, pid)
917
918    def attach_uprobe(self, name=b"", sym=b"", sym_re=b"", addr=None,
919            fn_name=b"", pid=-1):
920        """attach_uprobe(name="", sym="", sym_re="", addr=None, fn_name=""
921                         pid=-1)
922
923        Run the bpf function denoted by fn_name every time the symbol sym in
924        the library or binary 'name' is encountered. The real address addr may
925        be supplied in place of sym. Optional parameters pid, cpu, and group_fd
926        can be used to filter the probe.
927
928        Instead of a symbol name, a regular expression can be provided in
929        sym_re. The uprobe will then attach to symbols that match the provided
930        regular expression.
931
932        Libraries can be given in the name argument without the lib prefix, or
933        with the full path (/usr/lib/...). Binaries can be given only with the
934        full path (/bin/sh). If a PID is given, the uprobe will attach to the
935        version of the library used by the process.
936
937        Example: BPF(text).attach_uprobe("c", "malloc")
938                 BPF(text).attach_uprobe("/usr/bin/python", "main")
939        """
940
941        name = _assert_is_bytes(name)
942        sym = _assert_is_bytes(sym)
943        sym_re = _assert_is_bytes(sym_re)
944        fn_name = _assert_is_bytes(fn_name)
945
946        if sym_re:
947            addresses = BPF.get_user_addresses(name, sym_re)
948            self._check_probe_quota(len(addresses))
949            for sym_addr in addresses:
950                self.attach_uprobe(name=name, addr=sym_addr,
951                                   fn_name=fn_name, pid=pid)
952            return
953
954        (path, addr) = BPF._check_path_symbol(name, sym, addr, pid)
955
956        self._check_probe_quota(1)
957        fn = self.load_func(fn_name, BPF.KPROBE)
958        ev_name = self._get_uprobe_evname(b"p", path, addr, pid)
959        fd = lib.bpf_attach_uprobe(fn.fd, 0, ev_name, path, addr, pid)
960        if fd < 0:
961            raise Exception("Failed to attach BPF to uprobe")
962        self._add_uprobe_fd(ev_name, fd)
963        return self
964
965    def attach_uretprobe(self, name=b"", sym=b"", sym_re=b"", addr=None,
966            fn_name=b"", pid=-1):
967        """attach_uretprobe(name="", sym="", sym_re="", addr=None, fn_name=""
968                            pid=-1)
969
970        Run the bpf function denoted by fn_name every time the symbol sym in
971        the library or binary 'name' finishes execution. See attach_uprobe for
972        meaning of additional parameters.
973        """
974
975        name = _assert_is_bytes(name)
976        sym = _assert_is_bytes(sym)
977        sym_re = _assert_is_bytes(sym_re)
978        fn_name = _assert_is_bytes(fn_name)
979
980        if sym_re:
981            for sym_addr in BPF.get_user_addresses(name, sym_re):
982                self.attach_uretprobe(name=name, addr=sym_addr,
983                                      fn_name=fn_name, pid=pid)
984            return
985
986        (path, addr) = BPF._check_path_symbol(name, sym, addr, pid)
987
988        self._check_probe_quota(1)
989        fn = self.load_func(fn_name, BPF.KPROBE)
990        ev_name = self._get_uprobe_evname(b"r", path, addr, pid)
991        fd = lib.bpf_attach_uprobe(fn.fd, 1, ev_name, path, addr, pid)
992        if fd < 0:
993            raise Exception("Failed to attach BPF to uretprobe")
994        self._add_uprobe_fd(ev_name, fd)
995        return self
996
997    def detach_uprobe_event(self, ev_name):
998        if ev_name not in self.uprobe_fds:
999            raise Exception("Uprobe %s is not attached" % ev_name)
1000        res = lib.bpf_close_perf_event_fd(self.uprobe_fds[ev_name])
1001        if res < 0:
1002            raise Exception("Failed to detach BPF from uprobe")
1003        res = lib.bpf_detach_uprobe(ev_name)
1004        if res < 0:
1005            raise Exception("Failed to detach BPF from uprobe")
1006        self._del_uprobe_fd(ev_name)
1007
1008    def detach_uprobe(self, name=b"", sym=b"", addr=None, pid=-1):
1009        """detach_uprobe(name="", sym="", addr=None, pid=-1)
1010
1011        Stop running a bpf function that is attached to symbol 'sym' in library
1012        or binary 'name'.
1013        """
1014
1015        name = _assert_is_bytes(name)
1016        sym = _assert_is_bytes(sym)
1017        (path, addr) = BPF._check_path_symbol(name, sym, addr, pid)
1018        ev_name = self._get_uprobe_evname(b"p", path, addr, pid)
1019        self.detach_uprobe_event(ev_name)
1020
1021    def detach_uretprobe(self, name=b"", sym=b"", addr=None, pid=-1):
1022        """detach_uretprobe(name="", sym="", addr=None, pid=-1)
1023
1024        Stop running a bpf function that is attached to symbol 'sym' in library
1025        or binary 'name'.
1026        """
1027
1028        name = _assert_is_bytes(name)
1029        sym = _assert_is_bytes(sym)
1030
1031        (path, addr) = BPF._check_path_symbol(name, sym, addr, pid)
1032        ev_name = self._get_uprobe_evname(b"r", path, addr, pid)
1033        self.detach_uprobe_event(ev_name)
1034
1035    def _trace_autoload(self):
1036        for i in range(0, lib.bpf_num_functions(self.module)):
1037            func_name = lib.bpf_function_name(self.module, i)
1038            if func_name.startswith(b"kprobe__"):
1039                fn = self.load_func(func_name, BPF.KPROBE)
1040                self.attach_kprobe(
1041                    event=self.fix_syscall_fnname(func_name[8:]),
1042                    fn_name=fn.name)
1043            elif func_name.startswith(b"kretprobe__"):
1044                fn = self.load_func(func_name, BPF.KPROBE)
1045                self.attach_kretprobe(
1046                    event=self.fix_syscall_fnname(func_name[11:]),
1047                    fn_name=fn.name)
1048            elif func_name.startswith(b"tracepoint__"):
1049                fn = self.load_func(func_name, BPF.TRACEPOINT)
1050                tp = fn.name[len(b"tracepoint__"):].replace(b"__", b":")
1051                self.attach_tracepoint(tp=tp, fn_name=fn.name)
1052            elif func_name.startswith(b"raw_tracepoint__"):
1053                fn = self.load_func(func_name, BPF.RAW_TRACEPOINT)
1054                tp = fn.name[len(b"raw_tracepoint__"):]
1055                self.attach_raw_tracepoint(tp=tp, fn_name=fn.name)
1056
1057    def trace_open(self, nonblocking=False):
1058        """trace_open(nonblocking=False)
1059
1060        Open the trace_pipe if not already open
1061        """
1062        if not self.tracefile:
1063            self.tracefile = open("%s/trace_pipe" % TRACEFS, "rb")
1064            if nonblocking:
1065                fd = self.tracefile.fileno()
1066                fl = fcntl.fcntl(fd, fcntl.F_GETFL)
1067                fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
1068        return self.tracefile
1069
1070    def trace_fields(self, nonblocking=False):
1071        """trace_fields(nonblocking=False)
1072
1073        Read from the kernel debug trace pipe and return a tuple of the
1074        fields (task, pid, cpu, flags, timestamp, msg) or None if no
1075        line was read (nonblocking=True)
1076        """
1077        while True:
1078            line = self.trace_readline(nonblocking)
1079            if not line and nonblocking: return (None,) * 6
1080            # don't print messages related to lost events
1081            if line.startswith(b"CPU:"): continue
1082            task = line[:16].lstrip()
1083            line = line[17:]
1084            ts_end = line.find(b":")
1085            pid, cpu, flags, ts = line[:ts_end].split()
1086            cpu = cpu[1:-1]
1087            # line[ts_end:] will have ": [sym_or_addr]: msgs"
1088            # For trace_pipe debug output, the addr typically
1089            # is invalid (e.g., 0x1). For kernel 4.12 or earlier,
1090            # if address is not able to match a kernel symbol,
1091            # nothing will be printed out. For kernel 4.13 and later,
1092            # however, the illegal address will be printed out.
1093            # Hence, both cases are handled here.
1094            line = line[ts_end + 1:]
1095            sym_end = line.find(b":")
1096            msg = line[sym_end + 2:]
1097            return (task, int(pid), int(cpu), flags, float(ts), msg)
1098
1099    def trace_readline(self, nonblocking=False):
1100        """trace_readline(nonblocking=False)
1101
1102        Read from the kernel debug trace pipe and return one line
1103        If nonblocking is False, this will block until ctrl-C is pressed.
1104        """
1105
1106        trace = self.trace_open(nonblocking)
1107
1108        line = None
1109        try:
1110            line = trace.readline(1024).rstrip()
1111        except IOError:
1112            pass
1113        return line
1114
1115    def trace_print(self, fmt=None):
1116        """trace_print(self, fmt=None)
1117
1118        Read from the kernel debug trace pipe and print on stdout.
1119        If fmt is specified, apply as a format string to the output. See
1120        trace_fields for the members of the tuple
1121        example: trace_print(fmt="pid {1}, msg = {5}")
1122        """
1123
1124        while True:
1125            if fmt:
1126                fields = self.trace_fields(nonblocking=False)
1127                if not fields: continue
1128                line = fmt.format(*fields)
1129            else:
1130                line = self.trace_readline(nonblocking=False)
1131            print(line)
1132            sys.stdout.flush()
1133
1134    @staticmethod
1135    def _sym_cache(pid):
1136        """_sym_cache(pid)
1137
1138        Returns a symbol cache for the specified PID.
1139        The kernel symbol cache is accessed by providing any PID less than zero.
1140        """
1141        if pid < 0 and pid != -1:
1142            pid = -1
1143        if not pid in BPF._sym_caches:
1144            BPF._sym_caches[pid] = SymbolCache(pid)
1145        return BPF._sym_caches[pid]
1146
1147    @staticmethod
1148    def sym(addr, pid, show_module=False, show_offset=False, demangle=True):
1149        """sym(addr, pid, show_module=False, show_offset=False)
1150
1151        Translate a memory address into a function name for a pid, which is
1152        returned. When show_module is True, the module name is also included.
1153        When show_offset is True, the instruction offset as a hexadecimal
1154        number is also included in the string.
1155
1156        A pid of less than zero will access the kernel symbol cache.
1157
1158        Example output when both show_module and show_offset are True:
1159            "start_thread+0x202 [libpthread-2.24.so]"
1160
1161        Example output when both show_module and show_offset are False:
1162            "start_thread"
1163        """
1164        name, offset, module = BPF._sym_cache(pid).resolve(addr, demangle)
1165        offset = b"+0x%x" % offset if show_offset and name is not None else b""
1166        name = name or b"[unknown]"
1167        name = name + offset
1168        module = b" [%s]" % os.path.basename(module) \
1169            if show_module and module is not None else b""
1170        return name + module
1171
1172    @staticmethod
1173    def ksym(addr, show_module=False, show_offset=False):
1174        """ksym(addr)
1175
1176        Translate a kernel memory address into a kernel function name, which is
1177        returned. When show_module is True, the module name ("kernel") is also
1178        included. When show_offset is true, the instruction offset as a
1179        hexadecimal number is also included in the string.
1180
1181        Example output when both show_module and show_offset are True:
1182            "default_idle+0x0 [kernel]"
1183        """
1184        return BPF.sym(addr, -1, show_module, show_offset, False)
1185
1186    @staticmethod
1187    def ksymname(name):
1188        """ksymname(name)
1189
1190        Translate a kernel name into an address. This is the reverse of
1191        ksym. Returns -1 when the function name is unknown."""
1192        return BPF._sym_cache(-1).resolve_name(None, name)
1193
1194    def num_open_kprobes(self):
1195        """num_open_kprobes()
1196
1197        Get the number of open K[ret]probes. Can be useful for scenarios where
1198        event_re is used while attaching and detaching probes.
1199        """
1200        return len(self.kprobe_fds)
1201
1202    def num_open_uprobes(self):
1203        """num_open_uprobes()
1204
1205        Get the number of open U[ret]probes.
1206        """
1207        return len(self.uprobe_fds)
1208
1209    def num_open_tracepoints(self):
1210        """num_open_tracepoints()
1211
1212        Get the number of open tracepoints.
1213        """
1214        return len(self.tracepoint_fds)
1215
1216    def perf_buffer_poll(self, timeout = -1):
1217        """perf_buffer_poll(self)
1218
1219        Poll from all open perf ring buffers, calling the callback that was
1220        provided when calling open_perf_buffer for each entry.
1221        """
1222        readers = (ct.c_void_p * len(self.perf_buffers))()
1223        for i, v in enumerate(self.perf_buffers.values()):
1224            readers[i] = v
1225        lib.perf_reader_poll(len(readers), readers, timeout)
1226
1227    def kprobe_poll(self, timeout = -1):
1228        """kprobe_poll(self)
1229
1230        Deprecated. Use perf_buffer_poll instead.
1231        """
1232        self.perf_buffer_poll(timeout)
1233
1234    def donothing(self):
1235        """the do nothing exit handler"""
1236
1237    def cleanup(self):
1238        # Clean up opened probes
1239        for k, v in list(self.kprobe_fds.items()):
1240            self.detach_kprobe_event(k)
1241        for k, v in list(self.uprobe_fds.items()):
1242            self.detach_uprobe_event(k)
1243        for k, v in list(self.tracepoint_fds.items()):
1244            self.detach_tracepoint(k)
1245        for k, v in list(self.raw_tracepoint_fds.items()):
1246            self.detach_raw_tracepoint(k)
1247
1248        # Clean up opened perf ring buffer and perf events
1249        table_keys = list(self.tables.keys())
1250        for key in table_keys:
1251            if isinstance(self.tables[key], PerfEventArray):
1252                del self.tables[key]
1253        for (ev_type, ev_config) in list(self.open_perf_events.keys()):
1254            self.detach_perf_event(ev_type, ev_config)
1255        if self.tracefile:
1256            self.tracefile.close()
1257            self.tracefile = None
1258        if self.module:
1259            lib.bpf_module_destroy(self.module)
1260            self.module = None
1261
1262    def __enter__(self):
1263        return self
1264
1265    def __exit__(self, exc_type, exc_val, exc_tb):
1266        self.cleanup()
1267
1268
1269from .usdt import USDT, USDTException
1270