コード例 #1
0
        /// <summary>
        /// FUNCTION: Send
        /// PURPOSE : To send a pdu in order to set the MIB values
        /// </summary>
        public bool Send()
        {
            bool Success = false; // init success to failure

            try
            {
                if (VBLInit)
                {
                    if (Vbl.Item.Count > 0)
                    {
                        SNMPAPI_STATUS Result = new SNMPAPI_STATUS(); // set up a result item

                        // create entities for the source and destination addresses
                        IntPtr Source = SnmpAPI.SnmpStrToEntity(Session, LocalAddr);
                        IntPtr Destin = SnmpAPI.SnmpStrToEntity(Session, RemoteAddr);

                        // create arrays to hold Variable Info
                        SMIOID[]    OID         = new SMIOID[Vbl.Item.Count];    // an array of oids
                        SMIVALUE[]  Val         = new SMIVALUE[Vbl.Item.Count];  // an array of values
                        SMIOCTETS[] Oct         = new SMIOCTETS[Vbl.Item.Count]; // an array of octets
                        SMIOCTETS   DestOct     = new SMIOCTETS();               // the destination octect
                        GCHandle[]  PinnedArray = new GCHandle[Vbl.Item.Count];  // an array of pinned memory
                        byte[][]    ba          = new byte[Vbl.Item.Count][];    // a multi-dimensional byte array
                        IntPtr      VbL1        = new IntPtr();                  // pointer to variable bindings list
                        IntPtr      Context     = new IntPtr();                  // pointer to a context object

                        // start looping through all items in the variable bindings list
                        for (int i = 0; i < Vbl.Item.Count; i++)
                        {
                            ba[i] = new byte[((VARIABLE_ITEM)Vbl.Item[i]).Value.Length]; // new byte array

                            // check to see if the user has passed the separator
                            if (Vbl.ParentEntity.Substring(Vbl.ParentEntity.Length - 1, 1) != "." &&
                                ((VARIABLE_ITEM)Vbl.Item[i]).Entity.Substring(0, 1) != ".")
                            {
                                Result = SnmpAPI.SnmpStrToOid(Vbl.ParentEntity + "." + ((VARIABLE_ITEM)Vbl.Item[i]).Entity, ref OID[i]);
                            }
                            else
                            {
                                Result = SnmpAPI.SnmpStrToOid(Vbl.ParentEntity + ((VARIABLE_ITEM)Vbl.Item[i]).Entity, ref OID[i]);
                            }

                            // check result
                            if (Result == SNMPAPI_STATUS.SNMPAPI_FAILURE)
                            {
                                throw new Exception("SNMP OID Creation Failure");
                            }

                            // create the octet and value for this variable
                            Oct[i].size    = (uint)((VARIABLE_ITEM)Vbl.Item[i]).Value.Length;             // set the octet size
                            ba[i]          = Encoding.ASCII.GetBytes(((VARIABLE_ITEM)Vbl.Item[i]).Value); // encode string to byte array
                            PinnedArray[i] = GCHandle.Alloc(ba[i], GCHandleType.Pinned);                  // this creates a static memory location
                            Oct[i].octets  = PinnedArray[i].AddrOfPinnedObject();                         // set the octet pointer

                            // now, check what type of variable this is and set the value accordingly
                            switch (((VARIABLE_ITEM)Vbl.Item[i]).Type)
                            {
                            case VARIABLE_TYPE.VARIABLE_TYPE_INT:
                                Val[i].type        = SNMPAPI_SYNTAX.SNMP_SYNTAX_INT;
                                Val[i].val.sNumber = int.Parse(((VARIABLE_ITEM)Vbl.Item[i]).Value);
                                break;

                            case VARIABLE_TYPE.VARIABLE_TYPE_INT32:
                                Val[i].type        = SNMPAPI_SYNTAX.SNMP_SYNTAX_INT32;
                                Val[i].val.hNumber = long.Parse(((VARIABLE_ITEM)Vbl.Item[i]).Value);
                                break;

                            case VARIABLE_TYPE.VARIABLE_TYPE_OCTECT:
                                Val[i].type    = SNMPAPI_SYNTAX.SNMP_SYNTAX_OCTETS;
                                Val[i].val.str = Oct[i];
                                break;
                            }

                            // check to see if this is the first item, or an item to append
                            if (i == 0)
                            {
                                VbL1 = SnmpAPI.SnmpCreateVbl(Session, ref OID[i], ref Val[i]);
                            }
                            else
                            {
                                Result = SnmpAPI.SnmpSetVb(VbL1, 0, ref OID[i], ref Val[i]);
                            }
                        }
                        // now, set up the protocol description unit
                        IntPtr Pdu = SnmpAPI.SnmpCreatePdu(Session, (int)SNMPAPI_PDU.SNMP_PDU_SET, Vbl.RequestID, 0, 0, VbL1);

                        // set the destination octet (we only need to set the first one, the rest will flow accordingly)
                        DestOct.size   = (uint)((VARIABLE_ITEM)Vbl.Item[0]).Value.Length;
                        DestOct.octets = PinnedArray[0].AddrOfPinnedObject();
                        Context        = SnmpAPI.SnmpStrToContext(Session, ref DestOct);

                        // set the port to 162
                        Result = SnmpAPI.SnmpSetPort(Destin, 162);

                        // now send the messages
                        Result = SnmpAPI.SnmpSendMsg(Session, Source, Destin, Context, Pdu);


                        // SNMPAPI use requires us to handle some garbage collecting ourselves, else suffer memory leakage.

                        // free the context
                        Result = SnmpAPI.SnmpFreeContext(Context);

                        // free the pdu
                        Result = SnmpAPI.SnmpFreePdu(Pdu);

                        // free the variable lists
                        SnmpAPI.SnmpFreeVbl(VbL1);

                        for (int t = 0; t < Vbl.Item.Count; t++)
                        {
                            // free the pinned arrays
                            PinnedArray[t].Free();

                            // free the oids
                            SnmpAPI.SnmpFreeDescriptor((int)SNMPAPI_SYNTAX.SNMP_SYNTAX_OID, ref OID[t]);
                        }

                        // finally, free the entities
                        SnmpAPI.SnmpFreeEntity(Source);
                        SnmpAPI.SnmpFreeEntity(Destin);

                        Success = true;
                    }
                    else
                    {
                        throw new Exception("Variable Binding List Empty.");
                    }
                }
                else
                {
                    throw new Exception("Variable Binding Does Not Exist.");
                }
            }
            catch (Exception Err)
            {
                ErrMess = Err.Message;
            }
            return(Success); // return success flag
        }