From bb18f54a295727b060aef66cf40ea5ad6074233a Mon Sep 17 00:00:00 2001 From: Phil <phil@secdev.org> Date: Sun, 17 Aug 2008 01:23:07 +0200 Subject: [PATCH] Fixed SNMPv1 traps (D. Loss, ticket #99) --- scapy/asn1/asn1.py | 4 ++++ scapy/asn1/ber.py | 36 +++++++++++++++++++++++++++++++++++- scapy/asn1fields.py | 6 ++++++ scapy/layers/snmp.py | 10 ++++++---- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/scapy/asn1/asn1.py b/scapy/asn1/asn1.py index 0df885ad..c8c42f72 100644 --- a/scapy/asn1/asn1.py +++ b/scapy/asn1/asn1.py @@ -159,6 +159,7 @@ class ASN1_Class_UNIVERSAL(ASN1_Class): UNIVERSAL_STRING = 28 CHAR_STRING = 29 BMP_STRING = 30 + IPADDRESS = 0x40 COUNTER32 = 0x41 TIME_TICKS = 0x43 @@ -239,6 +240,9 @@ class ASN1_NUMERIC_STRING(ASN1_STRING): class ASN1_VIDEOTEX_STRING(ASN1_STRING): tag = ASN1_Class_UNIVERSAL.VIDEOTEX_STRING +class ASN1_IPADDRESS(ASN1_STRING): + tag = ASN1_Class_UNIVERSAL.IPADDRESS + class ASN1_UTC_TIME(ASN1_STRING): tag = ASN1_Class_UNIVERSAL.UTC_TIME diff --git a/scapy/asn1/ber.py b/scapy/asn1/ber.py index a74aa6c9..b567eaba 100644 --- a/scapy/asn1/ber.py +++ b/scapy/asn1/ber.py @@ -4,7 +4,7 @@ ## This program is published under a GPLv2 license from scapy.error import warning -from asn1 import ASN1_Decoding_Error,ASN1_BadTag_Decoding_Error,ASN1_Codecs,ASN1_Class_UNIVERSAL,ASN1_Error,ASN1_DECODING_ERROR,ASN1_BADTAG +from asn1 import ASN1_Decoding_Error,ASN1_Encoding_Error,ASN1_BadTag_Decoding_Error,ASN1_Codecs,ASN1_Class_UNIVERSAL,ASN1_Error,ASN1_DECODING_ERROR,ASN1_BADTAG ################## ## BER encoding ## @@ -18,6 +18,20 @@ from asn1 import ASN1_Decoding_Error,ASN1_BadTag_Decoding_Error,ASN1_Codecs,ASN1 class BER_Exception(Exception): pass +class BER_Encoding_Error(ASN1_Encoding_Error): + def __init__(self, msg, encoded=None, remaining=None): + Exception.__init__(self, msg) + self.remaining = remaining + self.encoded = encoded + def __str__(self): + s = Exception.__str__(self) + if isinstance(self.encoded, BERcodec_Object): + s+="\n### Already encoded ###\n%s" % self.encoded.strshow() + else: + s+="\n### Already encoded ###\n%r" % self.encoded + s+="\n### Remaining ###\n%r" % self.remaining + return s + class BER_Decoding_Error(ASN1_Decoding_Error): def __init__(self, msg, decoded=None, remaining=None): Exception.__init__(self, msg) @@ -239,6 +253,26 @@ class BERcodec_T61_STRING (BERcodec_STRING): class BERcodec_IA5_STRING(BERcodec_STRING): tag = ASN1_Class_UNIVERSAL.IA5_STRING +class BERcodec_IPADDRESS(BERcodec_STRING): + tag = ASN1_Class_UNIVERSAL.IPADDRESS + + @classmethod + def enc(cls, ipaddr_ascii): + try: + s = inet_aton(ipaddr_ascii) + except Exception: + raise BER_Encoding_Error("IPv4 address could not be encoded") + return chr(cls.tag)+BER_len_enc(len(s))+s + + @classmethod + def do_dec(cls, s, context=None, safe=False): + l,s,t = cls.check_type_check_len(s) + try: + ipaddr_ascii = inet_ntoa(s) + except Exception: + raise BER_Decoding_Error("IP address could not be decoded", decoded=obj) + return cls.asn1_object(ipaddr_ascii), t + class BERcodec_UTC_TIME(BERcodec_STRING): tag = ASN1_Class_UNIVERSAL.UTC_TIME diff --git a/scapy/asn1fields.py b/scapy/asn1fields.py index 3f564cbd..7351dad4 100644 --- a/scapy/asn1fields.py +++ b/scapy/asn1fields.py @@ -160,6 +160,12 @@ class ASN1F_PRINTABLE_STRING(ASN1F_STRING): class ASN1F_BIT_STRING(ASN1F_STRING): ASN1_tag = ASN1_Class_UNIVERSAL.BIT_STRING + +class ASN1F_IPADDRESS(ASN1F_STRING): + ASN1_tag = ASN1_Class_UNIVERSAL.IPADDRESS + +class ASN1F_TIME_TICKS(ASN1F_INTEGER): + ASN1_tag = ASN1_Class_UNIVERSAL.TIME_TICKS class ASN1F_UTC_TIME(ASN1F_STRING): ASN1_tag = ASN1_Class_UNIVERSAL.UTC_TIME diff --git a/scapy/layers/snmp.py b/scapy/layers/snmp.py index a3474472..0681825c 100644 --- a/scapy/layers/snmp.py +++ b/scapy/layers/snmp.py @@ -179,12 +179,11 @@ class SNMPset(ASN1_Packet): class SNMPtrapv1(ASN1_Packet): ASN1_codec = ASN1_Codecs.BER - ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_INTEGER("id",0), - ASN1F_OID("enterprise", "1.3"), - ASN1F_STRING("agent_addr",""), + ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_OID("enterprise", "1.3"), + ASN1F_IPADDRESS("agent_addr","0.0.0.0"), ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types), ASN1F_INTEGER("specific_trap", 0), - ASN1F_INTEGER("time_stamp", IntAutoTime()), + ASN1F_TIME_TICKS("time_stamp", IntAutoTime()), ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) ) @@ -231,6 +230,9 @@ class SNMP(ASN1_Packet): bind_layers( UDP, SNMP, sport=161) bind_layers( UDP, SNMP, dport=161) +bind_layers( UDP, SNMP, sport=162) +bind_layers( UDP, SNMP, dport=162) + def snmpwalk(dst, oid="1", community="public"): try: while 1: -- GitLab