Exemplo n.º 1
0
def declared_hostinfo(monkeypatch, request):
    data = [[
        ObjectName('.1.3.6.1.2.1.1.2.0'),
        ObjectIdentifier(request.param['sysobjectid'])
    ],
            [
                ObjectName('.1.3.6.1.2.1.1.1.0'),
                OctetString(request.param['description'])
            ]]
    get_oids = request.param.get('get_oids')
    if get_oids:
        for entry in get_oids:
            data.append([
                ObjectName(get_oids[entry]['oid']),
                OctetString(get_oids[entry]['value'])
            ])

    if 'walk_oids' in request.param.keys():
        get_next_return = []
        for extra_oid in request.param['walk_oids']:
            get_next_return.append([
                ObjectName('.' + request.param['walk_oids'][extra_oid]['oid']),
                OctetString(request.param['walk_oids'][extra_oid]['value'])
            ])
        walk_data = [get_next_return]
    else:
        walk_data = None
    return GetCmd(monkeypatch,
                  return_value=data,
                  walk_data=walk_data,
                  params=request.param)
Exemplo n.º 2
0
def declared_hostinfo(monkeypatch):
    data = [
        [ObjectName('.1.3.6.1.2.1.1.1.0'),
         OctetString('Cisco Adaptive Security Appliance Version 9.3(2)2')],
        [ObjectName('.1.3.6.1.2.1.1.2.0'),
         ObjectIdentifier('1.3.6.1.4.1.9.1.2114')],
        [ObjectName('.1.3.6.1.2.1.1.3.0'),
         OctetString('replace with uptime')],
        [ObjectName('.1.3.6.1.2.1.1.4.0'),
         OctetString('Networklore')],
        [ObjectName('.1.3.6.1.2.1.1.6.0'),
         OctetString('Westeros')],
    ]
    return GetCmd(monkeypatch, return_value=data)
Exemplo n.º 3
0
def return_snmp_data(value,value_type):
    if value_type is None:
        if isinstance(value, int):
            data = Integer(value)
        elif isinstance(value, float):
            data = Integer(value)
        elif isinstance(value, str):
            if is_ipv4_address(value):
                data = IpAddress(value)
            else:
                data = OctetString(value)
        else:
            raise TypeError(
                "Unable to autodetect type. Please pass one of "
                "these strings as the value_type keyword arg: "
                ", ".join(TYPES.keys())
            )
    else:
        if not value_type in TYPES:
            raise ValueError("'{}' is not one of the supported types: {}".format(
                value_type,
                ", ".join(TYPES.keys())
            ))

        data = TYPES[value_type](value)
    return data
Exemplo n.º 4
0
    def _get_var_binds(self, alert_values):

        var_binds = [(self.oids[field],
                      OctetString(alert_values.get(field, NA)))
                     for field in self.var_fields]

        return var_binds
Exemplo n.º 5
0
 def _get_snmpdata(self, *snmp_data):
     if self.return_value:
         return self.return_value
     else:
         for snmp in snmp_data:
             dat = snmp
         snmpdata = [[ObjectName('1.1'), OctetString(dat)]]
         return snmpdata
Exemplo n.º 6
0
    def set(self, oid, value, value_type=None):
        """
        Sets a single OID value. If you do not pass value_type hnmp will
        try to guess the correct type. Autodetection is supported for:

        * int and float (as Integer, fractional part will be discarded)
        * IPv4 address (as IpAddress)
        * str (as OctetString)

        Unfortunately, pysnmp does not support the SNMP FLOAT type so
        please use Integer instead.
        """
        snmpsecurity = self._get_snmp_security()

        if value_type is None:
            if isinstance(value, int):
                data = Integer(value)
            elif isinstance(value, float):
                data = Integer(value)
            elif isinstance(value, str):
                if is_ipv4_address(value):
                    data = IpAddress(value)
                else:
                    data = OctetString(value)
            else:
                raise TypeError(
                    "Unable to autodetect type. Please pass one of "
                    "these strings as the value_type keyword arg: "
                    ", ".join(TYPES.keys())
                )
        else:
            if value_type not in TYPES:
                raise ValueError("'{}' is not one of the supported types: {}".format(
                    value_type,
                    ", ".join(TYPES.keys())
                ))
            data = TYPES[value_type](value)

        try:
            engine_error, pdu_error, pdu_error_index, objects = self._cmdgen.setCmd(
                snmpsecurity,
                cmdgen.UdpTransportTarget((self.host, self.port), timeout=self.timeout,
                                          retries=self.retries),
                (oid, data),
            )
            if engine_error:
                raise SNMPError(engine_error)
            if pdu_error:
                raise SNMPError(pdu_error.prettyPrint())
        except Exception as e:
            raise SNMPError(e)

        _, value = objects[0]
        value = _convert_value_to_native(value)
        return value
    def test_var_binds(self):

        oid_with_alarm_objects = \
            common.GENERAL_OID + '.' + \
            common.COMPANY_OID + '.' + common.ALARM_OBJECTS_OID

        var_binds = self.snmp_sender._get_var_binds(common.alarm_data)

        self.assertEqual(len(var_binds), 3)

        self.assertIn(
            (oid_with_alarm_objects + '.' + common.NAME_OID,
             OctetString(common.alarm_data.get(VProps.NAME, sender.NA))),
            var_binds)
        self.assertIn(
            (oid_with_alarm_objects + '.' + common.IS_DELETED_OID,
             OctetString(common.alarm_data.get(VProps.IS_DELETED, sender.NA))),
            var_binds)
        self.assertIn((oid_with_alarm_objects + '.' + common.SEVERITY_OID,
                       OctetString(
                           common.alarm_data.get(VProps.OPERATIONAL_SEVERITY,
                                                 sender.NA))), var_binds)
Exemplo n.º 8
0
    def test_var_binds(self):

        oid_with_alarm_objects = \
            common.GENERAL_OID + '.' + \
            common.COMPANY_OID + '.' + common.ALARM_OBJECTS_OID

        var_binds = self.snmp_sender._get_var_binds(common.alarm_data)

        self.assertThat(var_binds, matchers.HasLength(3))

        self.assertIn((oid_with_alarm_objects + '.' + common.NAME_OID,
                      OctetString(common.alarm_data.get(VProps.NAME,
                                                        sender.NA))),
                      var_binds)
        self.assertIn((oid_with_alarm_objects + '.' + common.IS_DELETED_OID,
                       OctetString(common.alarm_data.get
                                   (VProps.VITRAGE_IS_DELETED, sender.NA))),
                      var_binds)
        self.assertIn((oid_with_alarm_objects + '.' + common.SEVERITY_OID,
                       OctetString(common.alarm_data.get
                                   (VProps.VITRAGE_OPERATIONAL_SEVERITY,
                                    sender.NA))),
                      var_binds)
Exemplo n.º 9
0
def getSnmpEngine(engineId=None):
    """Create SNMP engine instance.

    Args:
        engineId (str): SNMP engine ID as a ASCII or hex string

    Returns:
        object: SNMP engine object
    """
    if engineId:
        engineId = engineId.replace(':', '')

        if engineId.startswith('0x') or engineId.startswith('0X'):
            engineId = engineId[2:]

        engineId = OctetString(hexValue=engineId)

    return SnmpEngine(snmpEngineID=engineId)
Exemplo n.º 10
0
    def sendTrap(self, trap):
        trap_oid = trap['trap_oid']

        txAddress = self.args['--ipv6-host']
        txPort = self.args['--port']
        userData = UsmUserData('user-sha-aes128',
                               'authkey1',
                               'privkey1',
                               authProtocol=usmHMACSHAAuthProtocol,
                               privProtocol=usmAesCfb128Protocol)

        log.info("Sending SNMP Trap", address=txAddress, port=txPort)
        log.info("  Notification",
                 name=self.smd.getNameByNumOid(trap_oid),
                 oid=trap_oid)
        for var_bind in trap['var_binds']:
            var_oid = var_bind[0]
            var_val = var_bind[1]
            log.info("  with Object",
                     name=self.smd.getNameByNumOid(var_oid),
                     oid=var_oid,
                     type=type(var_val))

        trapOid = trap['trap_oid']
        txVarBinds = trap['var_binds']
        errorIndicationTx, errorStatusTx, errorIndexTx, varBindsTx = next(
            sendNotification(
                SnmpEngine(OctetString(hexValue='8000000001020304')), userData,
                Udp6TransportTarget((txAddress, txPort)), ContextData(),
                'trap',
                NotificationType(
                    ObjectIdentity(trapOid)).addVarBinds(*txVarBinds)))
        if errorIndicationTx:
            print(errorIndicationTx)
        else:
            for varBindTx in varBindsTx:
                print(' = '.join([x.prettyPrint() for x in varBindTx]))
Exemplo n.º 11
0
 def test_extract_classmaps():
     table = [[(ObjectName('1.3.6.1.4.1.9.9.166.1.7.1.1.1.748129779'),
                OctetString('cs6'))],
              [(ObjectName('1.3.6.1.4.1.9.9.166.1.7.1.1.1.1201419584'),
                OctetString('af4'))],
              [(ObjectName('1.3.6.1.4.1.9.9.166.1.7.1.1.1.1201419589'),
                OctetString('af1'))],
              [(ObjectName('1.3.6.1.4.1.9.9.166.1.7.1.1.1.1201419590'),
                OctetString('af2'))],
              [(ObjectName('1.3.6.1.4.1.9.9.166.1.7.1.1.1.1819748200'),
                OctetString('ef'))],
              [(ObjectName('1.3.6.1.4.1.9.9.166.1.7.1.1.1.1965376995'),
                OctetString('class-default'))]]
     class_maps = qos.extract_classmaps(table)
     expected = {
         '748129779': 'cs6',
         '1201419589': 'af1',
         '1201419584': 'af4',
         '1201419590': 'af2',
         '1965376995': 'class-default',
         '1819748200': 'ef'
     }
     assert_that(class_maps, has_entries(expected))
Exemplo n.º 12
0
#######################################
# Logging

import structlog
log = structlog.get_logger()

#####################################################################
# Configuration

DEFAULT_TYPE_TO_VALUE_MAP = {
    'DateAndTime': '2019-1-28,12:00:01.0,-4:0',
    'DisplayString': 'dummy_display_string',
    'InetAddress': '1.1.1.1',
    'InetAddressType': 'ipv4',
    'Ipv6Address': OctetString('aaaaaaaaaaaaaaaa'),
    'pysnmp.proto.rfc1902.Counter32': 10,
    'pysnmp.proto.rfc1902.Gauge32': 20,
    'pysnmp.proto.rfc1902.Integer32': 30,
    'pysnmp.proto.rfc1902.IpAddress': '1.1.1.1',
    'pysnmp.proto.rfc1902.OctetString': OctetString('abcdef'),
    'pysnmp.proto.rfc1902.Unsigned32': 40,
    'StarENBID': 1,
    'StarentCardType': 2,
    'StarLongDurTimeoutAction': 3,
    'StarOSPFNeighborState': 4,
    'StarShortName': 'dummy_shortname',
    'TruthValue': 'true',
    'InterfaceIndex':
    35,  # SYNTAX: Integer32 (1..2147483647), Ref - https://github.com/cisco-kusanagi/mibs.snmplabs.com/blob/master/asn1/IF-MIB#L76
}
Exemplo n.º 13
0
from pysnmp.proto.rfc1902 import Integer
from pysnmp.proto.rfc1902 import ObjectIdentifier
from pysnmp.proto.rfc1902 import ObjectName
from pysnmp.proto.rfc1902 import OctetString
from pysnmp.proto.rfc1902 import TimeTicks

from vitrage.snmp_parsing.service import SnmpParsingService
from vitrage.tests import base


BINDS_REPORTED = [
    (ObjectName('1.3.6.1.2.1.1.3.0'), TimeTicks(1491462248)),
    (ObjectName('1.3.6.1.6.3.1.1.4.1.0'),
     ObjectIdentifier('1.3.6.1.4.1.3902.4101.1.4.1.2')),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.3'),
     OctetString(hexValue='07e10406070408002b0800')),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.1.2'), Integer(0)),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.1.4'), Integer(0)),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.1.3'), OctetString('')),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.11'), OctetString('3305115653')),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.2'), OctetString('host')),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.4'), Integer(1)),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.5'), Integer(14)),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.6'), Integer(0)),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.7'), OctetString('')),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.8'),
     OctetString('vimid=,hid=controller_controller,'
                 'hostname=controller,'
                 'Reason: nova-compute is not available')),
    (ObjectName('1.3.6.1.4.1.3902.4101.1.3.1.12'),
     OctetString('Tecs Director')),
Exemplo n.º 14
0
    def load_section(self):
        obj = {'_name': '', '_children': []}

        state = 'FSM_START'

        while 1:
            # Initial state
            if state == 'FSM_START':
                try:
                    token, symbol = self.scanner.get_token()

                except error.EofError:
                    state = 'FSM_STOP'
                    continue

                self.scanner.unget_token()

                # See if it's object closure sign
                if symbol == SYMBOL_SECTION_END:
                    state = 'FSM_SECTION_END'

                # See if it's symbol sign
                elif symbol == SYMBOL_OPTION:
                    state = 'FSM_OPTION_NAME'

                # Default is to start from parsing up new section
                else:
                    state = 'FSM_SECTION_NAME'

            # If object name expected
            elif state == 'FSM_SECTION_NAME':
                self.scanner.get_token()

                self.scanner.unget_token()

                # Move to next FSM state
                state = 'FSM_SECTION_BEGIN'

            # If object body delimiter expected
            elif state == 'FSM_SECTION_BEGIN':
                self.scanner.get_token()

                # Get section begin
                token, symbol = self.scanner.get_token()

                # Now unget these tokens to be used at the
                # next FSM state
                self.scanner.unget_token()
                self.scanner.unget_token()

                # Make sure it's object's body start sign
                if symbol != SYMBOL_SECTION_BEGIN:
                    raise error.SnmpfwdError(
                        '%s missing object beginning sign: %s' % (self, token))

                state = 'FSM_CHILD_BEGIN'

            # If inclusive object expected
            elif state == 'FSM_CHILD_BEGIN':
                name, symbol = self.scanner.get_token()

                self.scanner.get_token()

                child_object = self.load_section()

                child_object['_name'] = name

                # Attach child object to the list of enclosed objects
                obj['_children'].append(child_object)

                state = 'FSM_CHILD_END'

            # If object body closure delimiter expected
            elif state == 'FSM_CHILD_END':
                # Get next token
                token, symbol = self.scanner.get_token()

                # Make sure it's object's body end sign
                if symbol != SYMBOL_SECTION_END:
                    raise error.SnmpfwdError(
                        '%s missing object closure sign: %s' % (self, token))

                # Move to the beginning of FSM
                state = 'FSM_START'

            # If object body closure delimiter expected
            elif state == 'FSM_SECTION_END':
                # Get next token
                token, symbol = self.scanner.get_token()

                # Now unget token to be used at upper level FSM instance
                self.scanner.unget_token()

                # Make sure it's object's body end sign
                if symbol != SYMBOL_SECTION_END:
                    raise error.SnmpfwdError(
                        '%s missing object closure sign: %s' % (self, token))

                # Move to next FSM state
                state = 'FSM_STOP'

            # If attribute name expected
            elif state == 'FSM_OPTION_NAME':
                # Get next token
                token, symbol = self.scanner.get_token()

                # See if this attribute does not yet exist
                if token in obj:
                    raise error.SnmpfwdError(
                        '%s multiple option occurrence: %s' % (self, token))

                # Accept token as attribute name
                obj[token] = []

                # Now unget token to be used at the next FSM state
                self.scanner.unget_token()

                # Move to next FSM state
                state = 'FSM_OPTION_VALUE'

            # If option value expected
            elif state == 'FSM_OPTION_VALUE':
                option, symbol = self.scanner.get_token()

                # Read up one or more option values
                while 1:
                    try:
                        token, symbol = self.scanner.get_token()

                    except error.EofError:
                        state = 'FSM_STOP'
                        break

                    # If it's not a plain word
                    if symbol != SYMBOL_WORD:
                        self.scanner.unget_token()

                        # See if it's object begin symbol
                        if symbol == SYMBOL_SECTION_BEGIN:
                            # Unget section begin sign
                            self.scanner.unget_token()

                            # Remove previously added last value of
                            # the list as it turned to be section name
                            del obj[option][-1]

                        # Move to the beginning of FSM
                        state = 'FSM_START'

                        break

                    # Accept token as attribute value
                    if token.lower()[:2] == '0x':
                        token = str(OctetString(hexValue=token[2:]))

                    obj[option].append(token)

            # If FSM is gonna stop
            elif state == 'FSM_STOP':
                # Return object loaded
                return obj

            # If this FSM state is not known
            else:
                raise error.SnmpfwdError('%s unknown FSM state: %s' %
                                         (self, state))
Exemplo n.º 15
0
def main():
    variation_module = None
    endpoints = {}
    contexts = {}

    stats = {
        'UDP packets': 0,
        'IP packets': 0,
        'bad packets': 0,
        'empty packets': 0,
        'unknown L2 protocol': 0,
        'SNMP errors': 0,
        'SNMP exceptions': 0,
        'agents seen': 0,
        'contexts seen': 0,
        'snapshots taken': 0,
        'Response PDUs seen': 0,
        'OIDs seen': 0
    }

    parser = argparse.ArgumentParser(description=DESCRIPTION)

    parser.add_argument('-v',
                        '--version',
                        action='version',
                        version=utils.TITLE)

    parser.add_argument('--quiet',
                        action='store_true',
                        help='Do not print out informational messages')

    parser.add_argument(
        '--debug',
        choices=pysnmp_debug.flagMap,
        action='append',
        type=str,
        default=[],
        help='Enable one or more categories of SNMP debugging.')

    parser.add_argument(
        '--debug-asn1',
        choices=pyasn1_debug.FLAG_MAP,
        action='append',
        type=str,
        default=[],
        help='Enable one or more categories of ASN.1 debugging.')

    parser.add_argument('--logging-method',
                        type=lambda x: x.split(':'),
                        metavar='=<%s[:args]>]' % '|'.join(log.METHODS_MAP),
                        default='stderr',
                        help='Logging method.')

    parser.add_argument('--log-level',
                        choices=log.LEVELS_MAP,
                        type=str,
                        default='info',
                        help='Logging level.')

    parser.add_argument(
        '--start-object',
        metavar='<MIB::Object|OID>',
        type=_parse_mib_object,
        default=univ.ObjectIdentifier('1.3.6'),
        help='Drop all simulation data records prior to this OID specified '
        'as MIB object (MIB::Object) or OID (1.3.6.)')

    parser.add_argument(
        '--stop-object',
        metavar='<MIB::Object|OID>',
        type=functools.partial(_parse_mib_object, last=True),
        help='Drop all simulation data records after this OID specified '
        'as MIB object (MIB::Object) or OID (1.3.6.)')

    parser.add_argument(
        '--mib-source',
        dest='mib_sources',
        metavar='<URI|PATH>',
        action='append',
        type=str,
        default=['http://mibs.snmplabs.com/asn1/@mib@'],
        help='One or more URIs pointing to a collection of ASN.1 MIB files.'
        'Optional "@mib@" token gets replaced with desired MIB module '
        'name during MIB search.')

    parser.add_argument(
        '--destination-record-type',
        choices=RECORD_TYPES,
        default='snmprec',
        help='Produce simulation data with record of this type')

    parser.add_argument('--output-file',
                        metavar='<FILE>',
                        type=str,
                        help='SNMP simulation data file to write records to')

    variation_group = parser.add_argument_group(
        'Simulation data variation options')

    variation_group.add_argument('--variation-modules-dir',
                                 action='append',
                                 type=str,
                                 help='Search variation module by this path')

    variation_group.add_argument(
        '--variation-module',
        type=str,
        help='Pass gathered simulation data through this variation module')

    variation_group.add_argument('--variation-module-options',
                                 type=str,
                                 default='',
                                 help='Variation module options')

    parser.add_argument(
        '--output-dir',
        metavar='<FILE>',
        type=str,
        default='.',
        help='SNMP simulation data directory to place captured traffic in '
        'form of simulation records. File names reflect traffic sources '
        'on the network.')

    variation_group.add_argument(
        '--transport-id-offset',
        type=int,
        default=0,
        help='When arranging simulation data files, start enumerating '
        'receiving transport endpoints from this number.')

    traffic_group = parser.add_argument_group('Traffic capturing options')

    traffic_group.add_argument(
        '--packet-filter',
        type=str,
        default='udp and src port 161',
        help='Traffic filter (in tcpdump syntax) to use for picking SNMP '
        'packets out of the rest of the traffic.')

    variation_group.add_argument('--listen-interface',
                                 type=str,
                                 help='Listen on this network interface.')

    parser.add_argument(
        '--promiscuous-mode',
        action='store_true',
        help='Attempt to switch NIC to promiscuous mode. Depending on the '
        'network, this may make traffic of surrounding machines visible. '
        'Might require superuser privileges.')

    parser.add_argument(
        '--capture-file',
        metavar='<FILE>',
        type=str,
        help='PCAP file with SNMP simulation data file to read from '
        'instead of listening on a NIC.')

    args = parser.parse_args()

    if not pcap:
        sys.stderr.write(
            'ERROR: pylibpcap package is missing!\r\nGet it by running '
            '`pip install '
            'https://downloads.sourceforge.net/project/pylibpcap/pylibpcap'
            '/0.6.4/pylibpcap-0.6.4.tar.gz`'
            '\r\n')
        parser.print_usage(sys.stderr)
        return 1

    proc_name = os.path.basename(sys.argv[0])

    try:
        log.set_logger(proc_name, *args.logging_method, force=True)

        if args.log_level:
            log.set_level(args.log_level)

    except error.SnmpsimError as exc:
        sys.stderr.write('%s\r\n%s\r\n' % exc)
        parser.print_usage(sys.stderr)
        sys.exit(1)

    if (isinstance(args.start_object, rfc1902.ObjectIdentity)
            or isinstance(args.stop_object, rfc1902.ObjectIdentity)):
        mib_builder = builder.MibBuilder()

        mib_view_controller = view.MibViewController(mib_builder)

        compiler.addMibCompiler(mib_builder, sources=args.mib_sources)

        try:
            if isinstance(args.start_object, rfc1902.ObjectIdentity):
                args.start_object.resolveWithMib(mib_view_controller)

            if isinstance(args.stop_object, rfc1902.ObjectIdentity):
                args.stop_object.resolveWithMib(mib_view_controller)

        except PySnmpError as exc:
            sys.stderr.write('ERROR: %s\r\n' % exc)
            return 1

    # Load variation module

    if args.variation_module:

        for variation_modules_dir in (args.variation_modules_dir
                                      or confdir.variation):
            log.info('Scanning "%s" directory for variation '
                     'modules...' % variation_modules_dir)

            if not os.path.exists(variation_modules_dir):
                log.info('Directory "%s" does not exist' %
                         variation_modules_dir)
                continue

            mod = os.path.join(variation_modules_dir,
                               args.variation_module + '.py')
            if not os.path.exists(mod):
                log.info('Variation module "%s" not found' % mod)
                continue

            ctx = {'path': mod, 'moduleContext': {}}

            try:
                with open(mod) as fl:
                    exec(compile(fl.read(), mod, 'exec'), ctx)

            except Exception as exc:
                log.error('Variation module "%s" execution '
                          'failure: %s' % (mod, exc))
                return 1

            variation_module = ctx
            log.info('Variation module "%s" loaded' % args.variation_module)
            break

        else:
            log.error('variation module "%s" not found' %
                      args.variation_module)
            return 1

    # Variation module initialization

    if variation_module:
        log.info('Initializing variation module...')

        for handler in ('init', 'record', 'shutdown'):
            if handler not in variation_module:
                log.error('missing "%s" handler at variation module '
                          '"%s"' % (handler, args.variation_module))
                return 1

        handler = variation_module['init']

        try:
            handler(options=args.variation_module_options,
                    mode='recording',
                    startOID=args.start_object,
                    stopOID=args.stop_object)

        except Exception as exc:
            log.error('Variation module "%s" initialization '
                      'FAILED: %s' % (args.variation_module, exc))

        else:
            log.info('Variation module "%s" '
                     'initialization OK' % args.variation_module)

    pcap_obj = pcap.pcapObject()

    if args.listen_interface:
        if not args.quiet:
            log.info('Listening on interface %s in %spromiscuous '
                     'mode' % (args.listen_interface,
                               '' if args.promiscuous_mode else 'non-'))

        try:
            pcap_obj.open_live(args.listen_interface, 65536,
                               args.promiscuous_mode, 1000)

        except Exception as exc:
            log.error('Error opening interface %s for snooping: '
                      '%s' % (args.listen_interface, exc))
            return 1

    elif args.capture_file:
        if not args.quiet:
            log.info('Opening capture file %s' % args.capture_file)

        try:
            pcap_obj.open_offline(args.capture_file)

        except Exception as exc:
            log.error('Error opening capture file %s for reading: '
                      '%s' % (args.capture_file, exc))
            return 1

    else:
        sys.stderr.write(
            'ERROR: no capture file or live interface specified\r\n')
        parser.print_usage(sys.stderr)
        return 1

    if args.packet_filter:
        if not args.quiet:
            log.info('Applying packet filter \"%s\"' % args.packet_filter)

        pcap_obj.setfilter(args.packet_filter, 0, 0)

    if not args.quiet:
        log.info('Processing records from %still '
                 '%s' %
                 ('the beginning ' if args.start_object else args.start_object,
                  args.stop_object if args.stop_object else 'the end'))

    def parse_packet(raw):
        pkt = {}

        # http://www.tcpdump.org/linktypes.html
        ll_headers = {0: 4, 1: 14, 108: 4, 228: 0}

        if pcap_obj.datalink() in ll_headers:
            raw = raw[ll_headers[pcap_obj.datalink()]:]

        else:
            stats['unknown L2 protocol'] += 1

        pkt['version'] = (ord(raw[0]) & 0xf0) >> 4
        pkt['header_len'] = ord(raw[0]) & 0x0f
        pkt['tos'] = ord(raw[1])
        pkt['total_len'] = socket.ntohs(struct.unpack('H', raw[2:4])[0])
        pkt['id'] = socket.ntohs(struct.unpack('H', raw[4:6])[0])
        pkt['flags'] = (ord(raw[6]) & 0xe0) >> 5
        pkt['fragment_offset'] = socket.ntohs(
            struct.unpack('H', raw[6:8])[0] & 0x1f)
        pkt['ttl'] = ord(raw[8])
        pkt['protocol'] = ord(raw[9])
        pkt['checksum'] = socket.ntohs(struct.unpack('H', raw[10:12])[0])
        pkt['source_address'] = pcap.ntoa(struct.unpack('i', raw[12:16])[0])
        pkt['destination_address'] = pcap.ntoa(
            struct.unpack('i', raw[16:20])[0])

        if pkt['header_len'] > 5:
            pkt['options'] = raw[20:4 * (pkt['header_len'] - 5)]

        else:
            pkt['options'] = None

        raw = raw[4 * pkt['header_len']:]

        if pkt['protocol'] == 17:
            pkt['source_port'] = socket.ntohs(struct.unpack('H', raw[0:2])[0])
            pkt['destination_port'] = socket.ntohs(
                struct.unpack('H', raw[2:4])[0])
            raw = raw[8:]
            stats['UDP packets'] += 1

        pkt['data'] = raw
        stats['IP packets'] += 1

        return pkt

    def handle_snmp_message(d, t, private={}):
        msg_ver = api.decodeMessageVersion(d['data'])

        if msg_ver in api.protoModules:
            p_mod = api.protoModules[msg_ver]

        else:
            stats['bad packets'] += 1
            return

        try:
            rsp_msg, whole_msg = decoder.decode(d['data'],
                                                asn1Spec=p_mod.Message())

        except PyAsn1Error:
            stats['bad packets'] += 1
            return

        if rsp_msg['data'].getName() == 'response':
            rsp_pdu = p_mod.apiMessage.getPDU(rsp_msg)
            error_status = p_mod.apiPDU.getErrorStatus(rsp_pdu)

            if error_status:
                stats['SNMP errors'] += 1

            else:
                endpoint = d['source_address'], d['source_port']

                if endpoint not in endpoints:
                    endpoints[endpoint] = udp.domainName + (
                        args.transport_id_offset + len(endpoints), )
                    stats['agents seen'] += 1

                context = '%s/%s' % (p_mod.ObjectIdentifier(
                    endpoints[endpoint]),
                                     p_mod.apiMessage.getCommunity(rsp_msg))

                if context not in contexts:
                    contexts[context] = {}
                    stats['contexts seen'] += 1

                context = '%s/%s' % (p_mod.ObjectIdentifier(
                    endpoints[endpoint]),
                                     p_mod.apiMessage.getCommunity(rsp_msg))

                stats['Response PDUs seen'] += 1

                if 'basetime' not in private:
                    private['basetime'] = t

                for oid, value in p_mod.apiPDU.getVarBinds(rsp_pdu):
                    if oid < args.start_object:
                        continue

                    if args.stop_object and oid >= args.stop_object:
                        continue

                    if oid in contexts[context]:
                        if value != contexts[context][oid]:
                            stats['snapshots taken'] += 1

                    else:
                        contexts[context][oid] = [], []

                    contexts[context][oid][0].append(t - private['basetime'])
                    contexts[context][oid][1].append(value)

                    stats['OIDs seen'] += 1

    def handle_packet(pktlen, data, timestamp):
        if not data:
            stats['empty packets'] += 1
            return

        handle_snmp_message(parse_packet(data), timestamp)

    try:
        if args.listen_interface:
            log.info('Listening on interface "%s", kill me when you '
                     'are done.' % args.listen_interface)

            while True:
                pcap_obj.dispatch(1, handle_packet)

        elif args.capture_file:
            log.info('Processing capture file "%s"....' % args.capture_file)

            args = pcap_obj.next()

            while args:
                handle_packet(*args)
                args = pcap_obj.next()

    except (TypeError, KeyboardInterrupt):
        log.info('Shutting down process...')

    finally:
        data_file_handler = SnmprecRecord()

        for context in contexts:
            ext = os.path.extsep
            ext += RECORD_TYPES[args.destination_record_type].ext

            filename = os.path.join(args.output_dir, context + ext)

            if not args.quiet:
                log.info('Creating simulation context %s at '
                         '%s' % (context, filename))

            try:
                os.mkdir(os.path.dirname(filename))

            except OSError:
                pass

            record = RECORD_TYPES[args.destination_record_type]

            try:
                output_file = record.open(filename, 'wb')

            except IOError as exc:
                log.error('writing %s: %s' % (filename, exc))
                return 1

            count = total = iteration = 0
            time_offset = 0
            req_time = time.time()

            oids = sorted(contexts[context])
            oids.append(oids[-1])  # duplicate last OID to trigger stopFlag

            while True:
                for oid in oids:

                    timeline, values = contexts[context][oid]

                    value = values[min(
                        len(values) - 1,
                        bisect.bisect_left(timeline, time_offset))]

                    if value.tagSet in (rfc1905.NoSuchObject.tagSet,
                                        rfc1905.NoSuchInstance.tagSet,
                                        rfc1905.EndOfMibView.tagSet):
                        stats['SNMP exceptions'] += 1
                        continue

                    # remove value enumeration

                    if value.tagSet == Integer32.tagSet:
                        value = Integer32(value)

                    if value.tagSet == Unsigned32.tagSet:
                        value = Unsigned32(value)

                    if value.tagSet == Bits.tagSet:
                        value = OctetString(value)

                    # Build .snmprec record

                    ctx = {
                        'origOid': oid,
                        'origValue': value,
                        'count': count,
                        'total': total,
                        'iteration': iteration,
                        'reqTime': req_time,
                        'startOID': args.start_object,
                        'stopOID': args.stop_object,
                        'stopFlag': oids.index(oid) == len(oids) - 1,
                        'variationModule': variation_module
                    }

                    try:
                        line = data_file_handler.format(oid, value, **ctx)

                    except error.MoreDataNotification as exc:
                        count = 0
                        iteration += 1

                        moreDataNotification = exc
                        if 'period' in moreDataNotification:
                            time_offset += moreDataNotification['period']
                            log.info(
                                '%s OIDs dumped, advancing time window to '
                                '%.2f sec(s)...' % (total, time_offset))
                        break

                    except error.NoDataNotification:
                        pass

                    except error.SnmpsimError as exc:
                        log.error(exc)
                        continue

                    else:
                        output_file.write(line)

                        count += 1
                        total += 1

                else:
                    break

            output_file.flush()
            output_file.close()

        if variation_module:
            log.info('Shutting down variation module '
                     '"%s"...' % args.variation_module)

            handler = variation_module['shutdown']

            try:
                handler(options=args.variation_module_options,
                        mode='recording')

            except Exception as exc:
                log.error('Variation module "%s" shutdown FAILED: '
                          '%s' % (args.variation_module, exc))

            else:
                log.info('Variation module "%s" shutdown'
                         ' OK' % args.variation_module)

        log.info("""\
PCap statistics:
    packets snooped: %s
    packets dropped: %s
    packets dropped: by interface %s\
    """ % pcap_obj.stats())

        log.info("""\
SNMP statistics:
    %s\
    """ % '    '.join(['%s: %s\r\n' % kv for kv in stats.items()]))

    return 0
Exemplo n.º 16
0
    def sendTrap(self, logRecord):
        """Send BDS log message as SNMP notification.

        Args:
            logRecord (dict): log record data as a Python `dict`
        """
        self.moduleLogger.info(f'sendTrap payload: {logRecord}')

        self._trapCounter += 1

        if self._trapCounter == 0xffffffff:
            self._trapCounter = 0

        try:
            syslogMsgFacility = logRecord['host']

        except KeyError:
            self.moduleLogger.error(
                f'cannot get syslog facility from {logRecord}')
            syslogMsgFacility = 'error'

        try:
            syslogMsgSeverity = logRecord['level']

        except KeyError:
            self.moduleLogger.error(
                f'cannot get syslog severity from {logRecord}')
            syslogMsgSeverity = 0

        try:
            syslogMsgText = logRecord['short_message']

        except KeyError:
            self.moduleLogger.error(
                f'cannot get syslog message text from bdsLogDict '
                f'{logRecord}')

            syslogMsgText = 'error'

        self.moduleLogger.info(
            f'data sendTrap {self._trapCounter} {syslogMsgFacility} '
            f'{syslogMsgSeverity} {syslogMsgText}')

        def cbFun(snmpEngine, sendRequestHandle, errorIndication,
                  errorStatus, errorIndex, varBinds, cbCtx):
            if errorIndication:
                self.moduleLogger.error(
                    f'notification {sendRequestHandle} failed: '
                    f'{errorIndication}')

            else:
                self.moduleLogger.error(
                    f'notification {sendRequestHandle} succeeded')

        uptime = int((time.time() - self._birthday) * 100)

        varBinds = [
            (self._sysUpTime, TimeTicks(uptime)),
            (self._snmpTrapOID, self._rtbrickSyslogTrap),
            (self._syslogMsgNumber, Unsigned32(self._trapCounter)),
            (self._syslogMsgFacility, OctetString(syslogMsgFacility)),
            (self._syslogMsgSeverity, Integer32(syslogMsgSeverity)),
            (self._syslogMsgText, OctetString(syslogMsgText))
        ]

        sendRequestHandle = self._ntfOrg.sendVarBinds(
            self._snmpEngine,
            # Notification targets
            self._targets,
            None, '',  # contextEngineId, contextName
            varBinds,
            cbFun
        )

        self.moduleLogger.info(
            f'notification {sendRequestHandle or ""} submitted')
Exemplo n.º 17
0
 def setUp(self):
     self.oids = {ObjectName('1.2.3.4'): OctetString('eth0')}
Exemplo n.º 18
0
    def set_interface_untagged_vlan(self, interface, new_vlan_id):
        """
        As an example, Override the VLAN change, this is done Comware specific using the Comware VLAN MIB
        Return -1 if invalid interface, or value of _set() call
        """
        dprint(f"Comware set_interface_untagged_vlan() port {interface.name} to {new_vlan_id}")
        new_vlan = self.get_vlan_by_id(new_vlan_id)
        if interface and new_vlan:
            if interface.is_tagged:
                dprint("Tagged/Trunk Mode!")
                # set the TRUNK_NATIVE_VLAN OID:
                low_vlan_list = PortList()
                low_vlan_list.from_byte_count(BYTES_FOR_2048_VLANS)
                high_vlan_list = PortList()
                high_vlan_list.from_byte_count(BYTES_FOR_2048_VLANS)
                # add the new vlan id:
                if new_vlan_id > 2048:
                    # set the propper bit, adjust by the offset!
                    high_vlan_list[new_vlan_id - 2048] = 1
                else:
                    low_vlan_list[new_vlan_id] = 1
                # now loop through all vlans in this port and set the bit for the vlan:
                for vlan in interface.vlans:
                    if vlan > 2048:
                        # set the propper bit, adjust by the offset!
                        high_vlan_list[vlan - 2048] = 1
                    else:
                        low_vlan_list[vlan] = 1

                # now setup the OIDs to send as an atomic set:
                # first set Low-VLANs (1-2048) on this port:
                # Comware needs bits in opposite order inside each byte! (go figure)
                # note that to_hex_string() is same as .__str__ representation,
                # but we use it for extra clarity!
                low_vlan_list.reverse_bits_in_bytes()
                low_oid = (f"{hh3cifVLANTrunkAllowListLow}.{interface.port_id}",
                           OctetString(hexValue=low_vlan_list.to_hex_string()))

                # next High-VLANs (2049-4096) on this port:
                # Comware needs bits in opposite order inside each byte! (go figure)
                high_vlan_list.reverse_bits_in_bytes()
                high_oid = (f"{hh3cifVLANTrunkAllowListHigh}.{interface.port_id}",
                            OctetString(hexValue=high_vlan_list.to_hex_string()))

                # finally, set untagged vlan:  dot1qPvid
                pvid_oid = (f"{dot1qPvid}.{interface.port_id}", Gauge32(new_vlan_id))

                # now send them all as an atomic set():
                # get the PySNMP helper to do the work with the OctetString() BitMaps:
                pysnmp = pysnmpHelper(self.switch)
                (error_status, details) = pysnmp.set_multiple([low_oid, high_oid, pvid_oid])
                if error_status:
                    self.error.status = True
                    self.error.description = "Error in setting vlan on tagged port!"
                    self.error.details = details
                    return -1

            else:
                # regular access mode untagged port:
                dprint("Acces Mode!")
                # create a PortList() to represent the ports/bits that are in the new vlan.
                # we need byte size from number of ethernet ports:
                max_port_id = self._get_max_qbridge_port_id()
                bytecount = math.ceil(max_port_id / 8)
                dprint(f"max_port_id = {max_port_id}, bytecount = {bytecount}")
                new_vlan_portlist = PortList()
                # initialize with "00" bytes
                new_vlan_portlist.from_byte_count(bytecount)
                # now set bit to 1 for this interface (i.e. set the port_id bit!):
                dprint(f"interface.port_id = {interface.port_id}")
                new_vlan_portlist[int(interface.port_id)] = 1
                # now loop to find other existing ports on this vlan:
                # dprint("Finding other ports on this vlan:")
                for (this_index, this_iface) in self.interfaces.items():
                    # dprint(f"{this_iface.name} (port {this_iface.port_id}), Tagged {this_iface.is_tagged}, \
                    #  untagged vlan {this_iface.untagged_vlan}, Vlan dict: {this_iface.vlans}")
                    if this_iface.type == IF_TYPE_ETHERNET:
                        if this_iface.port_id > -1:     # we have a valid PortId
                            if this_iface.is_tagged:
                                # tagged interface
                                # dprint("  Tagged")
                                # is the new vlanId active on this port (i.e. PVID or on trunk) ?
                                if (this_iface.untagged_vlan == new_vlan_id) or (new_vlan_id in this_iface.vlans):
                                    # dprint(" This port is needed on new vlan")
                                    # is this port in Current Egress PortList?
                                    # if not, do NOT add!
                                    # this can happen with a PVID set on a port in trunk mode, but
                                    # the trunk does not allow that vlan! (edge use case)
                                    if self.vlans[new_vlan_id].current_egress_portlist[this_iface.port_id]:
                                        # dprint("  and in allow list!")
                                        new_vlan_portlist[this_iface.port_id] = 1
                                    # else:
                                    #    dprint("  but NOT in allow list!")
                            else:
                                # untagged on this new vlanId ?
                                if (this_iface.untagged_vlan == new_vlan_id):
                                    # dprint("  Port PVID added to new vlan!")
                                    new_vlan_portlist[this_iface.port_id] = 1
                        else:
                            # no switchport? "should" not happen for a valid switch port interface
                            warning = f"Warning: {this_iface.name} - no port_id found in set_interface_untagged_vlan(Comware)!"
                            self._add_warning(warning)

                # send to the switch!
                # Comware needs bits in opposite order inside each byte! (go figure)
                new_vlan_portlist.reverse_bits_in_bytes()
                # get the PySNMP helper to do the work with this BitMap:
                # note that to_hex_string() is same as .__str__ representation,
                # but we use it for extra clarity!
                octet_string = OctetString(hexValue=new_vlan_portlist.to_hex_string())
                pysnmp = pysnmpHelper(self.switch)
                (error_status, details) = pysnmp.set(f"{hh3cdot1qVlanPorts}.{new_vlan_id}", octet_string)
                if error_status:
                    self.error.status = True
                    self.error.description = "Error in setting vlan on access port!"
                    self.error.details = details
                    return -1

            # now trick the next switch view into showing this as the vlan on the interface
            # without the need to re-read SNMP data! We could also just read it here :-)
            # self._parse_oid_and_cache(QBRIDGE_VLAN_IFACE_UNTAGGED_PVID + "." + str(if_index), str(new_vlan_id), 'u')

            # now we need to reread the interface to VLAN mib part
            self._get_port_vlan_membership()
            # and force data to be added to session cache again!
            self._set_http_session_cache()
            return 0
        # interface not found, return False!
        return -1
Exemplo n.º 19
0
            if value.tagSet in (rfc1905.NoSuchObject.tagSet,
                                rfc1905.NoSuchInstance.tagSet,
                                rfc1905.EndOfMibView.tagSet):
                stats['SNMP exceptions'] += 1
                continue

            # remove value enumeration

            if value.tagSet == Integer32.tagSet:
                value = Integer32(value)

            if value.tagSet == Unsigned32.tagSet:
                value = Unsigned32(value)

            if value.tagSet == Bits.tagSet:
                value = OctetString(value)

            # Build .snmprec record

            ctx = {
                'origOid': oid,
                'origValue': value,
                'count': count,
                'total': total,
                'iteration': iteration,
                'reqTime': reqTime,
                'startOID': startOID,
                'stopOID': stopOID,
                'stopFlag': oids.index(oid) == len(oids) - 1,
                'variationModule': variationModule
            }
Exemplo n.º 20
0
 def mynextcmd(*junk, **lookupMib):
     return None, None, None, [[[ObjectName('1.1'), OctetString('b')]]]
Exemplo n.º 21
0
    IpAddress,
    ObjectName,
    OctetString,
    TimeTicks,
    Unsigned32,
)

data = []
data.append([ObjectName('.1.'), Counter32('100'), 100])
data.append([ObjectName('.1.'), Counter64('100'), 100])
data.append([ObjectName('.1.'), Gauge32('100'), 100])
data.append([ObjectName('.1.'), Integer('100'), 100])
data.append([ObjectName('.1.'), Integer32('100'), 100])
data.append([ObjectName('.1.'), IpAddress('192.168.1.1'), '192.168.1.1'])
data.append([ObjectName('.1.'), ObjectIdentifier('1'), '1'])
data.append([ObjectName('.1.'), OctetString('my_string'), 'my_string'])
data.append([ObjectName('.1.'), Unsigned32('100'), 100])


@pytest.fixture(scope='function', params=data)
def query_data(monkeypatch, request):
    snmp_data = [[request.param[0], request.param[1]]]
    return GetCmdValues(monkeypatch,
                        return_value=snmp_data,
                        params=request.param)


def test_return_value_types(query_data):
    dev = SnmpHandler(host='1.1.1.1', version='2c', community='public')
    varbinds = dev.get('1')
    for oid, value in varbinds:
Exemplo n.º 22
0
Arquivo: dlink.py Projeto: jjjfx/dlink
    def get_config(self, timeout=10):
        """
        Метод для получения конфигурационного файла целевого оборудования.
        В методе определены oid'ы используемого оборудования.
        Метод работает следующим образом - по snmp запрашивается oid_sysname
        и по нему определяется тип оборудования, по типу оборудования
        запрашиваются соответствующие oid и на указанный TFTP сервер
        закачивается конфигурационный файл оборудования, далее он считывается
        в виде строки и удаляется с сервера.

        :param timeout: таймаут на получение конфигурационного файла

        :rtype: строка с конфигурационным файлом оборудования
        """

        try:
            if not self.eqp_type:
                self.get_eqp_type()

            if not self.firmware:
                self.get_firmware_version()

        except DlinkInitException as dlink_exc:
            logger.error(dlink_exc)
            raise DlinkConfigException(
                self.ip, 'дальнейшая работа с оборудованием невозможна')

        cfg_file_name = 'config-%s.cfg' % self.ip

        # набор oid'ов для конфигурации обрудования DES-3*** на отдачу
        # конфигурационного файла на TFTP сервер
        oids_des = (('1.3.6.1.4.1.171.12.1.2.1.1.3.3',
                     IpAddress(self.tftp_server)),
                    ('1.3.6.1.4.1.171.12.1.2.1.1.4.3',
                     Integer(2)), ('1.3.6.1.4.1.171.12.1.2.1.1.5.3',
                                   OctetString(cfg_file_name)),
                    ('1.3.6.1.4.1.171.12.1.2.1.1.6.3', Integer(3)),
                    ('1.3.6.1.4.1.171.12.1.2.1.1.7.3', Integer(2)),
                    ('1.3.6.1.4.1.171.12.1.2.1.1.8.3', Integer(3)))

        # набор oid'ов для конфигурации обрудования DGS-3*** на отдачу
        # конфигурационного файла на TFTP сервер
        oids_dgs = (('1.3.6.1.4.1.171.12.1.2.18.1.1.3.3',
                     IpAddress(self.tftp_server)),
                    ('1.3.6.1.4.1.171.12.1.2.18.1.1.5.3',
                     OctetString(cfg_file_name)),
                    ('1.3.6.1.4.1.171.12.1.2.18.1.1.8.3', Integer(2)),
                    ('1.3.6.1.4.1.171.12.1.2.18.1.1.12.3', Integer(3)))

        # набор oid'ов для конфигурации обрудования DGS-3100 на отдачу
        # конфигурационного файла на TFTP сервер
        oids_tg = (('1.3.6.1.4.1.171.10.94.89.89.87.2.1.4.1', IpAddress(
            self.ip)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.5.1',
                        Integer(1)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.6.1',
                                      OctetString('startupConfig')),
                   ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.7.1', Integer(3)),
                   ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.8.1',
                    Integer(3)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.9.1',
                                  IpAddress(self.tftp_server)),
                   ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.10.1',
                    Integer(1)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.11.1',
                                  OctetString(cfg_file_name)),
                   ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.12.1',
                    Integer(3)), ('1.3.6.1.4.1.171.10.94.89.89.87.2.1.17.1',
                                  Integer(4)))

        cfg_file_end = 'End of configuration file'

        # TG
        if 'DGS-3100' in self.eqp_type:
            current_eqp = oids_tg
            # переопределяем окончание конфигурационного файла для
            # оборудования DGS-3100
            cfg_file_end = '! VOICE VLAN'
        # DES-3526, DES-3528, DES-3010G, DGS-3200
        elif 'DES-3526' in self.eqp_type \
                or 'DES-3528' in self.eqp_type \
                or 'DES-3010G' in self.eqp_type \
                or 'DGS-3200' in self.eqp_type:
            current_eqp = oids_des
        # DGS
        elif 'DGS-3' in self.eqp_type:
            current_eqp = oids_dgs
        # DES
        elif 'DES-3' in self.eqp_type:
            if self.firmware:
                if float(self.firmware[:4]) >= 4.00:
                    current_eqp = oids_dgs
                else:
                    current_eqp = oids_des
            else:
                current_eqp = oids_des
        else:
            raise DlinkConfigException(
                self.ip, 'не удалось определить нужный набор oid '
                'для настройки оборудования на отдачу конфигурационного файла')

        # получаем конфиг, если определить тип оборудование не получилось,
        # то выводим соответствующее сообщение
        try:
            self.snmp.set(*current_eqp)
        except snmp.SnmpSetTimeoutException as snmp_exc:
            logger.critical(snmp_exc)
            raise DlinkConfigException(
                self.ip, 'не удалось настроить оборудование на отдачу '
                'конфигурационного файла')

        logger.debug(
            '%s - оборудование настроено на отдачу конфигурационного файла '
            'успешно' % self.ip)

        result = None

        file_path = os.path.join(self.tftp_path, cfg_file_name)

        if self.config_load_method == 'local':
            open_func = open
            rm_func = os.remove
            conn_close_func = lambda: None

        elif self.config_load_method == 'ssh':
            ssh = paramiko.SSHClient()
            ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
            ssh.load_system_host_keys()

            try:
                ssh.connect(self.tftp_server,
                            username=self.username,
                            password=self.password)
            except socket.error as exc:
                logger.error('%s - %s' % (self.ip, exc))
                raise DlinkConfigException(
                    self.ip, 'не удалось подключиться к серверу %s'
                    'по протоколу ssh' % self.tftp_server)

            sftp = ssh.open_sftp()

            open_func = sftp.open
            rm_func = sftp.remove
            conn_close_func = ssh.close

        else:
            raise DlinkConfigException(
                self.ip,
                'неверно указан метод загрузки конфигурационного файла')

        _c = 0

        while 1:
            time.sleep(1)
            if _c < timeout:
                try:
                    _f = open_func(file_path, mode='r')
                # обработка ситуации когда файл еще не создан
                except IOError as io_exc:
                    _c += 1
                else:
                    cfg_file = _f.read()
                    if cfg_file_end in cfg_file:
                        _f.close()
                        rm_func(file_path)
                        conn_close_func()
                        result = cfg_file.replace('\r\n', '\n')
                        break
                    else:
                        end_not_obtained = True
                        _c += 1
                        _f.close()
            else:
                conn_close_func()

                if 'io_exc' in locals():
                    raise DlinkConfigException(
                        self.ip, 'конфигурационного файла %s не существует '
                        'на сервере %s' % (file_path, self.tftp_server))
                elif 'end_not_obtained' in locals():
                    raise DlinkConfigException(
                        self.ip, 'конец файла %s не получен за %s секунд' %
                        (file_path, timeout))
                else:
                    raise DlinkConfigException(
                        self.ip, 'не удалось получить конфигурационный файл '
                        '%s с сервера %s по неизвестной причине' %
                        (file_path, self.tftp_server))

        logger.info('%s - конфигурационный файла получен успешно' % self.ip)
        self.chassis.config_file = result
        return result