Một ví dụ hoàn chỉnh: SNMP
SNMP xác định đối tượng ASN.1 mới. Chúng ta cần phải xác định họ:
Những vật thể này PDU, và trong thực tế tên mới cho một container chuỗi (điều này thường là trường hợp cho bối cảnh các đối tượng: họ là container cũ với tên mới). Điều này có nghĩa là tạo ra các đối tượng ASN.1 và codec BER tương ứng là đơn giản:
Metaclasses cung cấp sự kỳ diệu đằng sau thực tế là tất cả mọi thứ được tự động đăng ký và các đối tượng ASN.1 và codec BER có thể tìm thấy nhau.
Các trường ASN.1 cũng là tầm thường:
Bây giờ, phần khó khăn, các gói dữ liệu ASN.1:
Đó là không có nhiều khó khăn. Nếu bạn nghĩ không thể là ngắn để thực hiện SNMP mã hóa / giải mã và rằng tôi có thể có thể cắt giảm quá nhiều, chỉ cần nhìn vào các mã nguồn hoàn chỉnh.
Bây giờ, làm thế nào để sử dụng nó? Như thường lệ:
class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL): name="SNMP" PDU_GET = 0xa0 PDU_NEXT = 0xa1 PDU_RESPONSE = 0xa2 PDU_SET = 0xa3 PDU_TRAPv1 = 0xa4 PDU_BULK = 0xa5 PDU_INFORM = 0xa6 PDU_TRAPv2 = 0xa7
Những vật thể này PDU, và trong thực tế tên mới cho một container chuỗi (điều này thường là trường hợp cho bối cảnh các đối tượng: họ là container cũ với tên mới). Điều này có nghĩa là tạo ra các đối tượng ASN.1 và codec BER tương ứng là đơn giản:
class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE): tag = ASN1_Class_SNMP.PDU_GET class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE): tag = ASN1_Class_SNMP.PDU_NEXT # [...] class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE): tag = ASN1_Class_SNMP.PDU_GET class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE): tag = ASN1_Class_SNMP.PDU_NEXT # [...]
Metaclasses cung cấp sự kỳ diệu đằng sau thực tế là tất cả mọi thứ được tự động đăng ký và các đối tượng ASN.1 và codec BER có thể tìm thấy nhau.
Các trường ASN.1 cũng là tầm thường:
class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE): ASN1_tag = ASN1_Class_SNMP.PDU_GET class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE): ASN1_tag = ASN1_Class_SNMP.PDU_NEXT # [...]
Bây giờ, phần khó khăn, các gói dữ liệu ASN.1:
SNMP_error = { 0: "no_error", 1: "too_big", # [...] } SNMP_trap_types = { 0: "cold_start", 1: "warm_start", # [...] } class SNMPvarbind(ASN1_Packet): ASN1_codec = ASN1_Codecs.BER ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"), ASN1F_field("value",ASN1_NULL(0)) ) class SNMPget(ASN1_Packet): ASN1_codec = ASN1_Codecs.BER ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0), ASN1F_enum_INTEGER("error",0, SNMP_error), ASN1F_INTEGER("error_index",0), ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) ) class SNMPnext(ASN1_Packet): ASN1_codec = ASN1_Codecs.BER ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0), ASN1F_enum_INTEGER("error",0, SNMP_error), ASN1F_INTEGER("error_index",0), ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) ) # [...] class SNMP(ASN1_Packet): ASN1_codec = ASN1_Codecs.BER ASN1_root = ASN1F_SEQUENCE( ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}), ASN1F_STRING("community","public"), ASN1F_CHOICE("PDU", SNMPget(), SNMPget, SNMPnext, SNMPresponse, SNMPset, SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2) ) def answers(self, other): return ( isinstance(self.PDU, SNMPresponse) and ( isinstance(other.PDU, SNMPget) or isinstance(other.PDU, SNMPnext) or isinstance(other.PDU, SNMPset) ) and self.PDU.id == other.PDU.id ) # [...] bind_layers( UDP, SNMP, sport=161) bind_layers( UDP, SNMP, dport=161)
Đó là không có nhiều khó khăn. Nếu bạn nghĩ không thể là ngắn để thực hiện SNMP mã hóa / giải mã và rằng tôi có thể có thể cắt giảm quá nhiều, chỉ cần nhìn vào các mã nguồn hoàn chỉnh.
Bây giờ, làm thế nào để sử dụng nó? Như thường lệ:
>>> a=SNMP(version=3, PDU=SNMPget(varbindlist=[SNMPvarbind(oid="1.2.3",value=5), ... SNMPvarbind(oid="3.2.1",value="hello")])) >>> a.show() ###[ SNMP ]### version= v3 community= 'public' \PDU\ |###[ SNMPget ]### | id= 0 | error= no_error | error_index= 0 | \varbindlist\ | |###[ SNMPvarbind ]### | | oid= '1.2.3' | | value= 5 | |###[ SNMPvarbind ]### | | oid= '3.2.1' | | value= 'hello' >>> hexdump(a) 0000 30 2E 02 01 03 04 06 70 75 62 6C 69 63 A0 21 02 0......public.!. 0010 01 00 02 01 00 02 01 00 30 16 30 07 06 02 2A 03 ........0.0...*. 0020 02 01 05 30 0B 06 02 7A 01 04 05 68 65 6C 6C 6F ...0...z...hello >>> send(IP(dst="1.2.3.4")/UDP()/SNMP()) . Sent 1 packets. >>> SNMP(str(a)).show() ###[ SNMP ]### version= <ASN1_INTEGER[3L]> community= <ASN1_STRING['public']> \PDU\ |###[ SNMPget ]### | id= <ASN1_INTEGER[0L]> | error= <ASN1_INTEGER[0L]> | error_index= <ASN1_INTEGER[0L]> | \varbindlist\ | |###[ SNMPvarbind ]### | | oid= <ASN1_OID['.1.2.3']> | | value= <ASN1_INTEGER[5L]> | |###[ SNMPvarbind ]### | | oid= <ASN1_OID['.3.2.1']> | | value= <ASN1_STRING['hello']>
Comments
Post a Comment