1## This file is part of Scapy 2## See http://www.secdev.org/projects/scapy for more informations 3## Copyright (C) Philippe Biondi <phil@secdev.org> 4## This program is published under a GPLv2 license 5 6""" 7SNMP (Simple Network Management Protocol). 8""" 9 10from __future__ import print_function 11from scapy.packet import * 12from scapy.asn1packet import * 13from scapy.asn1fields import * 14from scapy.asn1.asn1 import * 15from scapy.asn1.ber import * 16from scapy.sendrecv import sr1 17from scapy.volatile import * 18from scapy.layers.inet import UDP, IP, ICMP 19 20########## 21## SNMP ## 22########## 23 24######[ ASN1 class ]###### 25 26class ASN1_Class_SNMP(ASN1_Class_UNIVERSAL): 27 name="SNMP" 28 PDU_GET = 0xa0 29 PDU_NEXT = 0xa1 30 PDU_RESPONSE = 0xa2 31 PDU_SET = 0xa3 32 PDU_TRAPv1 = 0xa4 33 PDU_BULK = 0xa5 34 PDU_INFORM = 0xa6 35 PDU_TRAPv2 = 0xa7 36 37 38class ASN1_SNMP_PDU_GET(ASN1_SEQUENCE): 39 tag = ASN1_Class_SNMP.PDU_GET 40 41class ASN1_SNMP_PDU_NEXT(ASN1_SEQUENCE): 42 tag = ASN1_Class_SNMP.PDU_NEXT 43 44class ASN1_SNMP_PDU_RESPONSE(ASN1_SEQUENCE): 45 tag = ASN1_Class_SNMP.PDU_RESPONSE 46 47class ASN1_SNMP_PDU_SET(ASN1_SEQUENCE): 48 tag = ASN1_Class_SNMP.PDU_SET 49 50class ASN1_SNMP_PDU_TRAPv1(ASN1_SEQUENCE): 51 tag = ASN1_Class_SNMP.PDU_TRAPv1 52 53class ASN1_SNMP_PDU_BULK(ASN1_SEQUENCE): 54 tag = ASN1_Class_SNMP.PDU_BULK 55 56class ASN1_SNMP_PDU_INFORM(ASN1_SEQUENCE): 57 tag = ASN1_Class_SNMP.PDU_INFORM 58 59class ASN1_SNMP_PDU_TRAPv2(ASN1_SEQUENCE): 60 tag = ASN1_Class_SNMP.PDU_TRAPv2 61 62 63######[ BER codecs ]####### 64 65class BERcodec_SNMP_PDU_GET(BERcodec_SEQUENCE): 66 tag = ASN1_Class_SNMP.PDU_GET 67 68class BERcodec_SNMP_PDU_NEXT(BERcodec_SEQUENCE): 69 tag = ASN1_Class_SNMP.PDU_NEXT 70 71class BERcodec_SNMP_PDU_RESPONSE(BERcodec_SEQUENCE): 72 tag = ASN1_Class_SNMP.PDU_RESPONSE 73 74class BERcodec_SNMP_PDU_SET(BERcodec_SEQUENCE): 75 tag = ASN1_Class_SNMP.PDU_SET 76 77class BERcodec_SNMP_PDU_TRAPv1(BERcodec_SEQUENCE): 78 tag = ASN1_Class_SNMP.PDU_TRAPv1 79 80class BERcodec_SNMP_PDU_BULK(BERcodec_SEQUENCE): 81 tag = ASN1_Class_SNMP.PDU_BULK 82 83class BERcodec_SNMP_PDU_INFORM(BERcodec_SEQUENCE): 84 tag = ASN1_Class_SNMP.PDU_INFORM 85 86class BERcodec_SNMP_PDU_TRAPv2(BERcodec_SEQUENCE): 87 tag = ASN1_Class_SNMP.PDU_TRAPv2 88 89 90 91######[ ASN1 fields ]###### 92 93class ASN1F_SNMP_PDU_GET(ASN1F_SEQUENCE): 94 ASN1_tag = ASN1_Class_SNMP.PDU_GET 95 96class ASN1F_SNMP_PDU_NEXT(ASN1F_SEQUENCE): 97 ASN1_tag = ASN1_Class_SNMP.PDU_NEXT 98 99class ASN1F_SNMP_PDU_RESPONSE(ASN1F_SEQUENCE): 100 ASN1_tag = ASN1_Class_SNMP.PDU_RESPONSE 101 102class ASN1F_SNMP_PDU_SET(ASN1F_SEQUENCE): 103 ASN1_tag = ASN1_Class_SNMP.PDU_SET 104 105class ASN1F_SNMP_PDU_TRAPv1(ASN1F_SEQUENCE): 106 ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv1 107 108class ASN1F_SNMP_PDU_BULK(ASN1F_SEQUENCE): 109 ASN1_tag = ASN1_Class_SNMP.PDU_BULK 110 111class ASN1F_SNMP_PDU_INFORM(ASN1F_SEQUENCE): 112 ASN1_tag = ASN1_Class_SNMP.PDU_INFORM 113 114class ASN1F_SNMP_PDU_TRAPv2(ASN1F_SEQUENCE): 115 ASN1_tag = ASN1_Class_SNMP.PDU_TRAPv2 116 117 118 119######[ SNMP Packet ]###### 120 121SNMP_error = { 0: "no_error", 122 1: "too_big", 123 2: "no_such_name", 124 3: "bad_value", 125 4: "read_only", 126 5: "generic_error", 127 6: "no_access", 128 7: "wrong_type", 129 8: "wrong_length", 130 9: "wrong_encoding", 131 10: "wrong_value", 132 11: "no_creation", 133 12: "inconsistent_value", 134 13: "resource_unavailable", 135 14: "commit_failed", 136 15: "undo_failed", 137 16: "authorization_error", 138 17: "not_writable", 139 18: "inconsistent_name", 140 } 141 142SNMP_trap_types = { 0: "cold_start", 143 1: "warm_start", 144 2: "link_down", 145 3: "link_up", 146 4: "auth_failure", 147 5: "egp_neigh_loss", 148 6: "enterprise_specific", 149 } 150 151class SNMPvarbind(ASN1_Packet): 152 ASN1_codec = ASN1_Codecs.BER 153 ASN1_root = ASN1F_SEQUENCE( ASN1F_OID("oid","1.3"), 154 ASN1F_field("value",ASN1_NULL(0)) 155 ) 156 157 158class SNMPget(ASN1_Packet): 159 ASN1_codec = ASN1_Codecs.BER 160 ASN1_root = ASN1F_SNMP_PDU_GET( ASN1F_INTEGER("id",0), 161 ASN1F_enum_INTEGER("error",0, SNMP_error), 162 ASN1F_INTEGER("error_index",0), 163 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 164 ) 165 166class SNMPnext(ASN1_Packet): 167 ASN1_codec = ASN1_Codecs.BER 168 ASN1_root = ASN1F_SNMP_PDU_NEXT( ASN1F_INTEGER("id",0), 169 ASN1F_enum_INTEGER("error",0, SNMP_error), 170 ASN1F_INTEGER("error_index",0), 171 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 172 ) 173 174class SNMPresponse(ASN1_Packet): 175 ASN1_codec = ASN1_Codecs.BER 176 ASN1_root = ASN1F_SNMP_PDU_RESPONSE( ASN1F_INTEGER("id",0), 177 ASN1F_enum_INTEGER("error",0, SNMP_error), 178 ASN1F_INTEGER("error_index",0), 179 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 180 ) 181 182class SNMPset(ASN1_Packet): 183 ASN1_codec = ASN1_Codecs.BER 184 ASN1_root = ASN1F_SNMP_PDU_SET( ASN1F_INTEGER("id",0), 185 ASN1F_enum_INTEGER("error",0, SNMP_error), 186 ASN1F_INTEGER("error_index",0), 187 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 188 ) 189 190class SNMPtrapv1(ASN1_Packet): 191 ASN1_codec = ASN1_Codecs.BER 192 ASN1_root = ASN1F_SNMP_PDU_TRAPv1( ASN1F_OID("enterprise", "1.3"), 193 ASN1F_IPADDRESS("agent_addr","0.0.0.0"), 194 ASN1F_enum_INTEGER("generic_trap", 0, SNMP_trap_types), 195 ASN1F_INTEGER("specific_trap", 0), 196 ASN1F_TIME_TICKS("time_stamp", IntAutoTime()), 197 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 198 ) 199 200class SNMPbulk(ASN1_Packet): 201 ASN1_codec = ASN1_Codecs.BER 202 ASN1_root = ASN1F_SNMP_PDU_BULK( ASN1F_INTEGER("id",0), 203 ASN1F_INTEGER("non_repeaters",0), 204 ASN1F_INTEGER("max_repetitions",0), 205 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 206 ) 207 208class SNMPinform(ASN1_Packet): 209 ASN1_codec = ASN1_Codecs.BER 210 ASN1_root = ASN1F_SNMP_PDU_INFORM( ASN1F_INTEGER("id",0), 211 ASN1F_enum_INTEGER("error",0, SNMP_error), 212 ASN1F_INTEGER("error_index",0), 213 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 214 ) 215 216class SNMPtrapv2(ASN1_Packet): 217 ASN1_codec = ASN1_Codecs.BER 218 ASN1_root = ASN1F_SNMP_PDU_TRAPv2( ASN1F_INTEGER("id",0), 219 ASN1F_enum_INTEGER("error",0, SNMP_error), 220 ASN1F_INTEGER("error_index",0), 221 ASN1F_SEQUENCE_OF("varbindlist", [], SNMPvarbind) 222 ) 223 224 225class SNMP(ASN1_Packet): 226 ASN1_codec = ASN1_Codecs.BER 227 ASN1_root = ASN1F_SEQUENCE( 228 ASN1F_enum_INTEGER("version", 1, {0:"v1", 1:"v2c", 2:"v2", 3:"v3"}), 229 ASN1F_STRING("community","public"), 230 ASN1F_CHOICE("PDU", SNMPget(), 231 SNMPget, SNMPnext, SNMPresponse, SNMPset, 232 SNMPtrapv1, SNMPbulk, SNMPinform, SNMPtrapv2) 233 ) 234 def answers(self, other): 235 return ( isinstance(self.PDU, SNMPresponse) and 236 ( isinstance(other.PDU, SNMPget) or 237 isinstance(other.PDU, SNMPnext) or 238 isinstance(other.PDU, SNMPset) ) and 239 self.PDU.id == other.PDU.id ) 240 241bind_layers( UDP, SNMP, sport=161) 242bind_layers( UDP, SNMP, dport=161) 243bind_layers( UDP, SNMP, sport=162) 244bind_layers( UDP, SNMP, dport=162) 245 246def snmpwalk(dst, oid="1", community="public"): 247 try: 248 while True: 249 r = sr1(IP(dst=dst)/UDP(sport=RandShort())/SNMP(community=community, PDU=SNMPnext(varbindlist=[SNMPvarbind(oid=oid)])),timeout=2, chainCC=1, verbose=0, retry=2) 250 if ICMP in r: 251 print(repr(r)) 252 break 253 if r is None: 254 print("No answers") 255 break 256 print("%-40s: %r" % (r[SNMPvarbind].oid.val,r[SNMPvarbind].value)) 257 oid = r[SNMPvarbind].oid 258 259 except KeyboardInterrupt: 260 pass 261 262