1 module snmp.pdu; 2 3 import c.net_snmp; 4 import snmp.types; 5 import snmp.oid; 6 7 private alias size_t = object.size_t; 8 import snmp.varbind; 9 10 /// Owns the response PDU from a synchronous SNMP request. 11 struct SNMPResponse 12 { 13 netsnmp_pdu* handle; 14 int status; 15 16 @disable this(this); 17 18 bool ok() const @trusted @nogc nothrow 19 { 20 return status == STAT_SUCCESS 21 && handle !is null 22 && handle.errstat == SNMP_ERR_NOERROR; 23 } 24 25 SNMPError errStatus() const @trusted @nogc nothrow 26 { 27 return handle 28 ? cast(SNMPError) handle.errstat 29 : SNMPError.genErr; 30 } 31 32 VarBind variables() const @trusted @nogc nothrow 33 { 34 return VarBind(handle ? cast(netsnmp_variable_list*) handle.variables : null); 35 } 36 37 size_t length() const @trusted @nogc nothrow 38 { 39 size_t n; 40 for (auto v = cast(netsnmp_variable_list*) (handle ? handle.variables : null); 41 v; v = v.next_variable) 42 ++n; 43 return n; 44 } 45 46 int opApply(scope int delegate(VarBind) dg) @trusted 47 { 48 for (auto v = variables; v.isValid; v = v.next) 49 if (auto r = dg(v)) 50 return r; 51 return 0; 52 } 53 54 ~this() @trusted @nogc nothrow { free_(); } 55 56 void free_() @trusted @nogc nothrow 57 { 58 if (handle) 59 { 60 snmp_free_pdu(handle); 61 handle = null; 62 } 63 } 64 } 65 66 unittest 67 { 68 auto r = SNMPResponse(null, STAT_ERROR); 69 assert(!r.ok); 70 assert(!r.variables.isValid); 71 assert(r.length == 0); 72 r.free_(); 73 74 auto t = SNMPResponse(null, STAT_TIMEOUT); 75 assert(!t.ok); 76 77 assert(r.errStatus == SNMPError.genErr); 78 79 int count; 80 foreach (v; r) 81 ++count; 82 assert(count == 0); 83 }