def parse(self, line): line = octs2str(line).strip(" \t\n\r") if line.startswith('#') or len(line)==0: # Ignore comment or empty line return None,None,None oid, tag, value = [ x.strip() for x in octs2str(line).split(',', 2) ] return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip())
def parse(self, line): line = line.decode('ascii', 'ignore').encode() # drop possible 8-bits try: oid, value = octs2str(line).strip().split(' = ', 1) except: raise error.SnmpsimError('broken record <%s>' % line) if oid and oid[0] == '.': oid = oid[1:] if value.startswith('Wrong Type (should be'): value = value[value.index(': ') + 2:] if value.startswith('No more variables left in this MIB View'): value = 'STRING: ' try: tag, value = value.split(' ', 1) except ValueError: # this is implicit snmpwalk's fuzziness if value == '""' or value == 'STRING:': tag = 'STRING:' value = '' else: tag = 'TimeTicks:' if oid and tag: return oid, tag.upper(), self.filterMap.get( tag.upper(), lambda x: x)(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): line = octs2str(line).strip(" \t\n\r") if line.startswith('#') or len(line)==0: # Ignore comment or empty line return None,None,None splitted = line.split('|', 2) return splitted[0],splitted[1],splitted[2]
def parse(self, line): filters = { 'OPAQUE:': self._opaque_filter, 'INTEGER:': self._integer_filter, 'STRING:': self._string_filter, 'BITS:': self._bits_filter, 'HEX-STRING:': self._hex_string_filter, 'GAUGE32:': self._gauge_filter, 'NETWORK ADDRESS:': self._net_address_filter, 'TIMETICKS:': self._time_ticks_filter } # drop possible 8-bits line = line.decode('ascii', 'ignore').encode() try: oid, value = octs2str(line).strip().split(' = ', 1) except Exception: raise error.SnmpsimError('broken record <%s>' % line) if oid and oid[0] == '.': oid = oid[1:] if value.startswith('Wrong Type (should be'): value = value[value.index(': ') + 2:] if value.startswith('No more variables left in this MIB View'): value = 'STRING: ' match = re.match(r'^(\w+(?:[\-\ ]\w+)?:)\ ?(.*)', value) if match: tag = match.group(1) value = match.group(2) # this is implicit snmpwalk's fuzziness elif value == '""' or value == 'STRING:': tag = 'STRING:' value = '' elif value == 'NULL': tag = 'NULL:' value = '' else: tag = 'TimeTicks:' if oid and tag: handler = filters.get(tag.upper(), lambda x: x) # Need rewrite tag for Network Address after filters if tag == 'Network Address:': tag = 'IpAddress:' return oid, tag.upper(), handler(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): try: oid, tag, value = octs2str(line).strip().split('|', 2) except: raise error.SnmpsimError('broken record <%s>' % line) else: if oid and tag: return oid, tag, value raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): try: oid, tag, value = [x.strip() for x in octs2str(line).split(',', 2)] except: raise error.SnmpsimError('broken record <%s>' % line) else: if oid and tag: return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): try: oid, tag, value = octs2str(line).split('|', 2) except: raise error.SnmpsimError('broken record <%s>' % line) else: if oid and tag: return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def prettyOut(self, value): if version_info[0] <= 2: numbers = tuple((ord(x) for x in value)) else: numbers = tuple(value) for x in numbers: if x < 32 or x > 126: return '0x' + ''.join(('%.2x' % x for x in numbers)) else: return octets.octs2str(value)
def parse(self, line): try: oid, tag, value = octs2str(line).split('|', 2) except Exception as exc: raise error.SnmpsimError( 'broken record <%s>: %s' % (line, exc)) else: if oid and tag: return oid.strip(), tag.strip(), value.strip("\r\n\t") raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): filters = { 'OPAQUE:': self._opaqueFilter, 'INTEGER:': self._integerFilter, 'STRING:': self._stringFilter, 'BITS:': self._bitsFilter, 'HEX-STRING:': self._hexStringFilter, 'GAUGE32:': self._gaugeFilter, 'Network Address:': self._netAddressFilter, 'TIMETICKS:': self._timeTicksFilter } # drop possible 8-bits line = line.decode('ascii', 'ignore').encode() try: oid, value = octs2str(line).strip().split(' = ', 1) except Exception: raise error.SnmpsimError('broken record <%s>' % line) if oid and oid[0] == '.': oid = oid[1:] if value.startswith('Wrong Type (should be'): value = value[value.index(': ') + 2:] if value.startswith('No more variables left in this MIB View'): value = 'STRING: ' try: tag, value = value.split(' ', 1) except ValueError: # this is implicit snmpwalk's fuzziness if value == '""' or value == 'STRING:': tag = 'STRING:' value = '' else: tag = 'TimeTicks:' if oid and tag: handler = filters.get(tag.upper(), lambda x: x) return oid, tag.upper(), handler(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): filters = {'4': self._nullFilter, '6': self._unhexFilter} try: oid, tag, value = octs2str(line).split('|', 2) except Exception: raise error.SnmpsimError('broken record <%s>' % line) else: if oid and tag: handler = filters.get(tag, lambda x: x) return oid, tag, handler(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): filters = {'OctetString': self._stringFilter} try: oid, tag, value = [x.strip() for x in octs2str(line).split(',', 2)] except Exception: raise error.SnmpsimError('broken record <%s>' % line) else: if oid and tag: handler = filters.get(tag, lambda x: x) return oid, tag, handler(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): filters = { 'OctetString': self._stringFilter } try: oid, tag, value = [x.strip() for x in octs2str(line).split(',', 2)] except Exception: raise error.SnmpsimError('broken record <%s>' % line) else: if oid and tag: handler = filters.get(tag, lambda x: x) return oid, tag, handler(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): oid, value = octs2str(line).strip().split(' = ', 1) if oid and oid[0] == '.': oid = oid[1:] if value.startswith('Wrong Type (should be'): value = value.partition(': ')[2] if value.startswith('No more variables left in this MIB View'): value = 'STRING: ' try: tag, value = value.split(' ', 1) except ValueError: # this is implicit snmpwalk's fuzziness if value == '""' or value == 'STRING:': tag = 'STRING:' value = '' else: tag = 'TimeTicks:' return oid, tag.upper(), self.filterMap.get(tag, lambda x: x)(value.strip())
def parse(self, line): filters = { '4': self._nullFilter, '6': self._unhexFilter } try: oid, tag, value = octs2str(line).split('|', 2) except Exception: raise error.SnmpsimError('broken record <%s>' % line) else: if oid and tag: handler = filters.get(tag, lambda x: x) return oid, tag, handler(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def evaluateValue(self, oid, tag, value, **context): tag, encodingId = self.unpackTag(tag) try: if encodingId == 'e': value = self.evaluateRawString(value) return oid, tag, self.grammar.TAG_MAP[tag](value) elif encodingId == 'x': if octets.isOctetsType(value): value = octets.octs2str(value) return oid, tag, self.grammar.TAG_MAP[tag](hexValue=value) else: return oid, tag, self.grammar.TAG_MAP[tag](value) except Exception: raise error.SnmpsimError( 'value evaluation error for tag %r, value ' '%r: %s' % (tag, value, sys.exc_info()[1]))
def evaluate_value(self, oid, tag, value, **context): tag, encoding_id = self.unpack_tag(tag) try: if encoding_id == 'e': value = self.evaluate_raw_string(value) return oid, tag, self.grammar.TAG_MAP[tag](value) elif encoding_id == 'x': if octets.isOctetsType(value): value = octets.octs2str(value) return oid, tag, self.grammar.TAG_MAP[tag](hexValue=value) else: return oid, tag, self.grammar.TAG_MAP[tag](value) except Exception as exc: raise error.SnmpsimError( 'value evaluation error for tag %r, value ' '%r: %s' % (tag, value, exc))
def parse(self, line): line = line.decode('ascii', 'ignore').encode() # drop possible 8-bits try: oid, value = octs2str(line).strip().split(' = ', 1) except: raise error.SnmpsimError('broken record <%s>' % line) if oid and oid[0] == '.': oid = oid[1:] if value.startswith('Wrong Type (should be'): value = value[value.index(': ')+2:] if value.startswith('No more variables left in this MIB View'): value = 'STRING: ' try: tag, value = value.split(' ', 1) except ValueError: # this is implicit snmpwalk's fuzziness if value == '""' or value == 'STRING:': tag = 'STRING:' value = '' else: tag = 'TimeTicks:' if oid and tag: return oid, tag.upper(), self.filterMap.get(tag.upper(), lambda x: x)(value.strip()) raise error.SnmpsimError('broken record <%s>' % line)
def parse(self, line): line = octs2str(line).strip(" \t\n\r").decode('ascii', 'ignore').encode() # drop possible 8-bits if line.startswith('#') or len(line)==0: # Ignore comment or empty line return None,None,None splitted = line.split(' = ', 1) oid = splitted[0] value = splitted[1] if oid and oid[0] == '.': oid = oid[1:] if value.startswith('Wrong Type (should be'): value = value[value.index(': ')+2:] if value.startswith('No more variables left in this MIB View'): value = 'STRING: ' try: tag, value = value.split(' ', 1) except ValueError: # this is implicit snmpwalk's fuzziness if value == '""' or value == 'STRING:': tag = 'STRING:' value = '' else: tag = 'TimeTicks:' return oid, tag.upper(), self.filterMap.get(tag, lambda x: x)(value.strip())
def test_octs2str(self): assert '\x01\x02\x03' == octets.octs2str(bytes([1, 2, 3]))
def test_octs2str_empty(self): assert not octets.octs2str('')
def test_octs2str(self): assert '\x01\x02\x03' == octets.octs2str('\x01\x02\x03')
def test_octs2str_empty(self): assert not octets.octs2str(bytes([]))
def prettyIn(self, value): # override asn1 type method """Implements DISPLAY-HINT parsing into base SNMP value Proper parsing seems impossible due to ambiguities. Here we are trying to do our best, but be prepared for failures on complicated DISPLAY-HINTs. Keep in mind that this parser only works with "text" input meaning `unicode` (Py2) or `str` (Py3). """ for base in inspect.getmro(self.__class__): if not issubclass(base, TextualConvention) and issubclass(base, Asn1Item): break else: raise SmiError('TEXTUAL-CONVENTION has no underlying SNMP base type') if self.displayHint and (self.__integer.isSuperTypeOf(self, matchConstraints=False) and self.getNamedValues() or self.__unsigned32.isSuperTypeOf(self, matchConstraints=False) or self.__timeticks.isSuperTypeOf(self, matchConstraints=False)): value = str(value) _ = lambda t, f=0: (t, f) displayHintType, decimalPrecision = _(*self.displayHint.split('-')) if displayHintType == 'x' and (value.startswith('0x') or value.startswith('-0x')): try: if value.startswith('-'): return base.prettyIn(self, -int(value[3:], 16)) else: return base.prettyIn(self, int(value[2:], 16)) except Exception as exc: raise SmiError( 'integer evaluation error: %s' % exc ) elif displayHintType == 'd': try: return base.prettyIn(self, int(float(value) * 10**int(decimalPrecision))) except Exception as exc: raise SmiError( 'float evaluation error: %s' % exc ) elif displayHintType == 'o' and (value.startswith('0') or value.startswith('-0')): try: return base.prettyIn(self, int(value, 8)) except Exception as exc: raise SmiError( 'octal evaluation error: %s' % exc ) elif displayHintType == 'b' and (value.startswith('B') or value.startswith('-B')): negative = value.startswith('-') if negative: value = value[2:] else: value = value[1:] value = [x != '0' and 1 or 0 for x in value] binValue = 0 while value: binValue <<= value[0] del value[0] return base.prettyIn(self, binValue) else: raise SmiError( 'Unsupported numeric type spec "%s" at %s' % (displayHintType, self.__class__.__name__) ) elif self.displayHint and self.__octetString.isSuperTypeOf(self, matchConstraints=False): numBase = { 'x': 16, 'd': 10, 'o': 8 } numDigits = { 'x': octets.str2octs(string.hexdigits), 'o': octets.str2octs(string.octdigits), 'd': octets.str2octs(string.digits) } # how do we know if object is initialized with display-hint # formatted text? based on "text" input maybe? # That boils down to `str` object on Py3 or `unicode` on Py2. if octets.isStringType(value) and not octets.isOctetsType(value): value = base.prettyIn(self, value) else: return base.prettyIn(self, value) outputValue = octets.str2octs('') runningValue = value displayHint = self.displayHint while runningValue and displayHint: # 1 this information is totally lost, just fail explicitly if displayHint[0] == '*': raise SmiError( 'Can\'t parse "*" in DISPLAY-HINT (%s)' % self.__class__.__name__ ) # 2 this becomes ambiguous when it comes to rendered value octetLength = '' while displayHint and displayHint[0] in string.digits: octetLength += displayHint[0] displayHint = displayHint[1:] # length is mandatory but people ignore that if not octetLength: octetLength = len(runningValue) try: octetLength = int(octetLength) except Exception: raise SmiError( 'Bad octet length: %s' % octetLength ) if not displayHint: raise SmiError( 'Short octet length: %s' % self.displayHint ) # 3 displayFormat = displayHint[0] displayHint = displayHint[1:] # 4 this is the lifesaver -- we could use it as an anchor if displayHint and displayHint[0] not in string.digits and displayHint[0] != '*': displaySep = displayHint[0] displayHint = displayHint[1:] else: displaySep = '' # 5 is probably impossible to support if displayFormat in ('a', 't'): outputValue += runningValue[:octetLength] elif displayFormat in numBase: if displaySep: guessedOctetLength = runningValue.find(octets.str2octs(displaySep)) if guessedOctetLength == -1: guessedOctetLength = len(runningValue) else: for idx in range(len(runningValue)): if runningValue[idx] not in numDigits[displayFormat]: guessedOctetLength = idx break else: guessedOctetLength = len(runningValue) try: num = int(octets.octs2str(runningValue[:guessedOctetLength]), numBase[displayFormat]) except Exception as exc: raise SmiError( 'Display format eval failure: %s: %s' % (runningValue[:guessedOctetLength], exc) ) num_as_bytes = [] if num: while num: num_as_bytes.append(num & 0xFF) num >>= 8 else: num_as_bytes = [0] while len(num_as_bytes) < octetLength: num_as_bytes.append(0) num_as_bytes.reverse() outputValue += octets.ints2octs(num_as_bytes) if displaySep: guessedOctetLength += 1 octetLength = guessedOctetLength else: raise SmiError( 'Unsupported display format char: %s' % displayFormat ) runningValue = runningValue[octetLength:] if not displayHint: displayHint = self.displayHint return base.prettyIn(self, outputValue) else: return base.prettyIn(self, value)
def evalsha(dbConn, *args): ret = dbConn.evalsha(*args) if ret is not None: ret = octets.octs2str(ret) return ret
def parse(self, line): oid, tag, value = [ x.strip() for x in octs2str(line).split(',', 2) ] return oid, tag, self.filterMap.get(tag, lambda x: x)(value.strip())
def get(dbConn, *args): ret = dbConn.get(*args) if ret is not None: ret = octets.octs2str(ret) return ret
def lindex(dbConn, *args): ret = dbConn.lindex(*args) if ret is not None: ret = octets.octs2str(ret) return ret
def prettyIn(self, value): # override asn1 type method """Implements DISPLAY-HINT parsing into base SNMP value Proper parsing seems impossible due to ambiguities. Here we are trying to do our best, but be prepared for failures on complicated DISPLAY-HINTs. Keep in mind that this parser only works with "text" input meaning `unicode` (Py2) or `str` (Py3). """ for base in inspect.getmro(self.__class__): if not issubclass(base, TextualConvention) and issubclass( base, Asn1Item): break else: raise SmiError( 'TEXTUAL-CONVENTION has no underlying SNMP base type') if self.displayHint and ( self.__integer.isSuperTypeOf(self, matchConstraints=False) and self.getNamedValues() or self.__unsigned32.isSuperTypeOf( self, matchConstraints=False) or self.__timeticks.isSuperTypeOf(self, matchConstraints=False)): value = str(value) _ = lambda t, f=0: (t, f) displayHintType, decimalPrecision = _(*self.displayHint.split('-')) if displayHintType == 'x' and (value.startswith('0x') or value.startswith('-0x')): try: if value.startswith('-'): return base.prettyIn(self, -int(value[3:], 16)) else: return base.prettyIn(self, int(value[2:], 16)) except Exception: raise SmiError('integer evaluation error: %s' % sys.exc_info()[1]) elif displayHintType == 'd': try: return base.prettyIn( self, int(float(value) * 10**int(decimalPrecision))) except Exception: raise SmiError('float evaluation error: %s' % sys.exc_info()[1]) elif displayHintType == 'o' and (value.startswith('0') or value.startswith('-0')): try: return base.prettyIn(self, int(value, 8)) except Exception: raise SmiError('octal evaluation error: %s' % sys.exc_info()[1]) elif displayHintType == 'b' and (value.startswith('B') or value.startswith('-B')): negative = value.startswith('-') if negative: value = value[2:] else: value = value[1:] value = [x != '0' and 1 or 0 for x in value] binValue = 0 while value: binValue <<= value[0] del value[0] return base.prettyIn(self, binValue) else: raise SmiError('Unsupported numeric type spec "%s" at %s' % (displayHintType, self.__class__.__name__)) elif self.displayHint and self.__octetString.isSuperTypeOf( self, matchConstraints=False): numBase = {'x': 16, 'd': 10, 'o': 8} numDigits = { 'x': octets.str2octs(string.hexdigits), 'o': octets.str2octs(string.octdigits), 'd': octets.str2octs(string.digits) } # how do we know if object is initialized with display-hint # formatted text? based on "text" input maybe? # That boils down to `str` object on Py3 or `unicode` on Py2. if octets.isStringType(value) and not octets.isOctetsType(value): value = base.prettyIn(self, value) else: return base.prettyIn(self, value) outputValue = octets.str2octs('') runningValue = value displayHint = self.displayHint while runningValue and displayHint: # 1 this information is totally lost, just fail explicitly if displayHint[0] == '*': raise SmiError('Can\'t parse "*" in DISPLAY-HINT (%s)' % self.__class__.__name__) # 2 this becomes ambiguous when it comes to rendered value octetLength = '' while displayHint and displayHint[0] in string.digits: octetLength += displayHint[0] displayHint = displayHint[1:] # length is mandatory but people ignore that if not octetLength: octetLength = len(runningValue) try: octetLength = int(octetLength) except Exception: raise SmiError('Bad octet length: %s' % octetLength) if not displayHint: raise SmiError('Short octet length: %s' % self.displayHint) # 3 displayFormat = displayHint[0] displayHint = displayHint[1:] # 4 this is the lifesaver -- we could use it as an anchor if displayHint and displayHint[ 0] not in string.digits and displayHint[0] != '*': displaySep = displayHint[0] displayHint = displayHint[1:] else: displaySep = '' # 5 is probably impossible to support if displayFormat in ('a', 't'): outputValue += runningValue[:octetLength] elif displayFormat in numBase: if displaySep: guessedOctetLength = runningValue.find( octets.str2octs(displaySep)) if guessedOctetLength == -1: guessedOctetLength = len(runningValue) else: for idx in range(len(runningValue)): if runningValue[idx] not in numDigits[ displayFormat]: guessedOctetLength = idx break else: guessedOctetLength = len(runningValue) try: num = int( octets.octs2str(runningValue[:guessedOctetLength]), numBase[displayFormat]) except Exception: raise SmiError('Display format eval failure: %s: %s' % (runningValue[:guessedOctetLength], sys.exc_info()[1])) num_as_bytes = [] if num: while num: num_as_bytes.append(num & 0xFF) num >>= 8 else: num_as_bytes = [0] while len(num_as_bytes) < octetLength: num_as_bytes.append(0) num_as_bytes.reverse() outputValue += octets.ints2octs(num_as_bytes) if displaySep: guessedOctetLength += 1 octetLength = guessedOctetLength else: raise SmiError('Unsupported display format char: %s' % displayFormat) runningValue = runningValue[octetLength:] if not displayHint: displayHint = self.displayHint return base.prettyIn(self, outputValue) else: return base.prettyIn(self, value)