[Top] [Prev] [Next] [Bottom]


5 - Setting Attribute Values

In addition to sending data and event reports, some agents can change the values of managed objects (that is, set attributes values). Sending a request to set the values of one or more attributes is very similar to sending a data or event request. The basic steps are:


1. Specify the system containing the attributes to set.


2. Set the values of any optional request arguments.


3. Specify each attribute and the value to set the attribute.


4. Send the set request to the agent. If the agent indicates it will be unable to set the requested attributes because the attribute is read-only or some other reason, fetch the error description and exit.


5. Run as an RPC callback server. When the callback function is dispatched, get the status message which indicates whether the agent succeeded in setting the requested attributes.

5.1 Specify Target System

The first call the manager makes in formulating a set request is to netmgt_set_instance(3n). This allows the agent to indicate the name of the <system> containing the attributes to be set. Unlike data and event requests, do not use netmgt_set_instance (3n) to specify the <group> or <key> names. You set these using netmgt_set_value(3n).


5.2 Set Optional Arguments

Sometimes the standard request mechanism isn't enough to get all needed information to an agent. The Manager Services library allows an option string to be specified. The definition of this field is up to the agent. For example, the ping agent uses the optional request arguments to set packet size, time to wait for echo replies, etc, because it is not possible to specify these parameters through the "standard" request mechanism.

You can also use the option string for SNMP requests. You can specify certain options that you want the SNMP proxy agent to use when sending an SNMP request to a target device. The optional arguments are:

If this option is used, the SNMP request is not sent to the target device, but will be sent instead to the specified proxy system. This argument should only be used only when a vendor has supplied an SNMP proxy agent to manage a particular device or set of devices. In this situation, the vendor's SNMP proxy agent communicates with the Site/SunNet/Domain Manager SNMP proxy agent via SNMP, but communicates with the target device using either SNMP or a different protocol.

  • na.snmp-get-list (used only for data reports)--list of object identifiers in standard dot notation. Separate each object ID with a space. For each object ID in the list, the SNMP proxy agent will get the value of the instance specified by the object ID.
  • na.snmp-get-next-list (used only for data reports)--list of object identifiers in standard dot notation. Separate each object ID with a space. For each object ID in the list, the SNMP proxy agent will get the value of the lexicographic next instance specified by the object ID.
  • na.snmp-timeout (number of seconds the SNMP proxy agent waits for a response from the target device)
  • If any optional arguments are to be specified, the manager should call netmgt_set_argument(3n).


    5.3 Specify Attribute Values

    For each attribute value to be set, the manager should call netmgt_set_value (3n). This allows the manager to specify the <group> containing the attribute, a <key> if the group is a table, the <name> of the attribute, and a <value> to set the attribute. You can request attributes in more than one group to be set using one request. The attributes just need to be set-able by one agent.


    5.4 Register to Receive Results

    Similar to data and event requests, agents perform set operations in three steps:

    1. Verify that they can perform the set request.


    2. Set the requested attributes.


    3. Send the set results to the manager.
    Managers get a request timestamp as the return value from the call to netmgt_request_set2(3n). To receive the results of the set operations, managers run as callback RPC servers. When the agent sends the set results, the manager's callback service function is called. The manager gets the set results by calling netmgt_fetch_error (3n).

    You should register your application as a temporary callback service by calling netmgt_register_callback (3n). This function registers a temporary (or transient) RPC service with the local portmapper which is described by portmap(8). Note, before exiting, the manager should unregister the RPC service by calling netmgt_unregister_callback (3n).


    5.5 Send Set Request

    You are now ready to send the set request by calling netmgt_request_set2(3n). When you send the request, the return value is the request timestamp if the request is successful. If the agent indicates it will not perform the request ( NULL is returned), get the reason for the failure by calling netmgt_fetch_error (3n).


    5.6 Get Set Results

    Assuming the netmgt_request_set2 (3n) return code indicated the agent will perform the request, run as a callback service to get the set results by calling svc_run(3n). When the agent sends the set results, your service dispatch function will be called with the following arguments:
    u_int type - report type. This will be NETMGT_SET_REPORT indicating the report argument contains the set results.

    char *system - name of the system where the attributes to be set reside.

    char *group - group name (always NULL).

    char *key - key name (always NULL).

    u_int count - reporting count (always zero).

    struct timeval interval - reporting interval (always zero).

    u_int flags - report flags.
    The dispatch function should call netmgt_fetch_error(3n) to get the set results. If the <service_error> is NETMGT_SUCCESS, the set request succeeded. Otherwise, the error buffer indicates the reason for the failure.


    5.7 Sample Code

    The following code fragment is an example of routines that send a set request to an SNMP agent and get the set results. The complete program example from which this fragment is taken is included in the product structure in the file set.c in the API_examples directory.




    #include <sys/param.h>
    #include <sys/types.h>
    #include <netmgt/netmgt.h>
    #include <rpc/rpcent.h>
    #include <signal.h>
    /* static functions */
    static bool_t   register_results();
    static void     display_results();
    static void     unregister_results();
    /* static data - global so exit handler can unregister RPC program */
    u_long  callback_prog;          /* callback RPC program number */
    char            agentname[NETMGT_NAMESIZ];      /* name of agent */
    char            target[MAXHOSTNAMELEN];         /* name of target system */
    char            agent_host[MAXHOSTNAMELEN];     /* agent hostname */
    char            event_host[MAXHOSTNAMELEN];     /* host where the event dispatcher runs*/
    /*---------------------------------------------------------------------
     * main routine
     *---------------------------------------------------------------------
     */
    int
    main (argc, argv)
    int argc;
    char ** argv;
    {
            char    local_host[MAXHOSTNAMELEN];     /* local host name */
            struct timeval  timeout;                /* request RPC timeout */
            Netmgt_setval   setval;                 /* attribute buffer*/
            char    *optstring= (char *) NULL;      /* optional string */
            u_int   flags = 0;                      /* request option flags */
            char    *location = "1st floor, room 101";
     





            /* sets the debug mode to print NETMGT_DBG messages */
            netmgt_debug = 1;
            timeout.tv_sec = NETMGT_TIMEOUT;
            timeout.tv_usec = 0;
            if (gethostname(local_host, sizeof(local_host)) == -1) {
                    perror("gethostname");
                    exit(1);
            }
            (void) strcpy(event_host, local_host);
            (void) strcpy(agent_host, local_host);
            (void) strcpy(target, local_host);
            (void) strcpy(agentname, "snmp");
            /* build set request argument */
            (void) strcpy(setval.group, "system");
            (void) strcpy(setval.key,"" );
            (void) strcpy(setval.name, "sysLocation");
            setval.type = NETMGT_STRING;
            setval.length = strlen(location) + 1;
            setval.value = location;
     
     
            /* send a set request - if it succeeds, run as a callback
             * RPC server waiting for the results
             */
     
            if (!do_set_request(target, &setval, &optstring, flags, timeout))
                    exit(1);
     
            /* request was verified */
            svc_run();
            exit(1);
     





    }
    /*---------------------------------------------------------------------
     * do_set_request - send a set request and get the request verification
     * returns TRUE if successful; otherwise returns FALSE
     *---------------------------------------------------------------------
     */
    bool_t
    do_set_request(target, setvalp,  optstring, flags, timeout)
     
            char    *target;        /* target system name */
            Netmgt_setval   *setvalp;/* set request argument */
            char    *optstring;     /* optional argument string */
            u_int   flags;          /* request flags */
            struct timeval timeout; /* RPC timeout */
    {
            u_long          agent_prog;     /* agent's RPC program number */
            struct rpcent *agent_rpc;       /* RPC database entry */
            Netmgt_arg      option;         /* option argument */
     
            /* get the agent's RPC info */
            agent_rpc = getrpcbyname(agentname);
            if (!agent_rpc) {
                    NETMGT_DBG("can't get RPC program number for %s\n", agentname);
                    return (FALSE);
            }
            agent_prog = agent_rpc->r_number;
             
     
            /* declare managed object instance */
            if (!netmgt_set_instance(target, (char *) NULL, (char *) NULL)) {
                    NETMGT_DBG("set_instance failed for %s: %s\n",
                        target, netmgt_sperror());
                    return (FALSE);
            }
     
    #ifdef SNMP_AGENT
            /* set SNMP arguments */
            set_snmp_args();
    #endif
     
     





            /* specifies the attribute to be set */
            if (!netmgt_set_value(setvalp)) {
                    NETMGT_DBG("set_value failed : %s\n", netmgt_sperror());
                    return (FALSE);
            }
     
     
            /* pass optional arguments */
            if (optstring) {
                    (void) strcpy(option.name, NETMGT_OPTSTRING);
                    option.type = NETMGT_STRING;
                    option.length = strlen(optstring) + 1;
                    option.value = optstring;
                    if (!netmgt_set_argument(&option)) {
                            NETMGT_DBG ("netmgt_set_argument failed: %s \n",
                                netmgt_sperror());
                            return (FALSE);
                    }
            }
     
            /* register a calback RPC program number to get results */
            if (!register_results(display_results))
                    return(FALSE);
     
     
            /* and send the request ... */
            if (!netmgt_request_set2(target, agent_prog, NETMGT_VERS,
                    event_host, callback_prog, NETMGT_VERS,
                    timeout, flags)) {
                    NETMGT_DBG("set_request failed : %s\n", netmgt_sperror());
                    return (FALSE);
            }
     
            return(TRUE);
    }
     
    /*
     * chapter 4.2: Optional Arguments
     */
     
     





    bool_t
    set_snmp_args()
    {
            /* argument for setting options */
            Netmgt_arg      option;
     
            /* write community string ( = default set during snmpd installation)*/
            char    *community= "private";
     
            NETMGT_DBG("setting snmp arguments \n");
             
            /* send SNMP write community */
            strcpy(option.name, "na.snmp-write-community");
            option.type = NETMGT_STRING;
            option.length = strlen(community) + 1;
            option.value = community;
            if  (!netmgt_set_argument(&option)) {
                    NETMGT_DBG ("netmgt_set_argument failed: %s \n",
                        netmgt_sperror());
                    return (FALSE);
            }
    }
     
    /*---------------------------------------------------------------------
     * register_results - register callback function
     * returns TRUE if successful; otherwise returns FALSE
     *---------------------------------------------------------------------
     */
     
    static bool_t
    register_results(callback)
            void (*callback) ();            /* callback function pointer */
    {
            int     udpSock;        /* UDP/IP socket descriptor */
            int     tcpSock;        /* TCP/IP socket descriptor */
            u_long  proto;          /* RPC transport protocol */
     
            NETMGT_DBG("register_results\n");
     
            udpSock = RPC_ANYSOCK;
            tcpSock = RPC_ANYSOCK;
            proto = (u_long) IPPROTO_UDP;
     





            if (! (callback_prog = netmgt_register_callback(callback, &udpSock,
                    &tcpSock, NETMGT_VERS, proto)) ) {
                    NETMGT_DBG("can't register RPC callback: %s\n",
                            netmgt_sperror());
                    return (FALSE);
            }
     
            /* declare exit handler to clean up */
            (void) signal(SIGINT, unregister_results);
            (void) signal(SIGQUIT, unregister_results);
            (void) signal(SIGTERM, unregister_results);
     
            NETMGT_DBG( "registered callback: prog == %d\n", callback_prog );
     
            return (TRUE);
    }
     
    /*---------------------------------------------------------------------
     * displays_results - displays results of set request and exit
     * no return
     *---------------------------------------------------------------------
     */
    static void
    display_results(type, system, group, key, count, interval, flags)
            u_int   type;           /* request type */
            char    *system;        /* target system name */
            char    *group;         /* object group name */
            char    *key;           /* object group key */
            u_int   count;          /* report count */
            struct timeval  interval;       /* report interval */
            u_int   flags;          /* report flags */
    {
            Netmgt_error    error;  /* error report argument */
     
            NETMGT_DBG("display_results\n");
     
            /* get error status */
            if (!netmgt_fetch_error(&error)) {
                    NETMGT_DBG("can't get set report: %s\n",
                             netmgt_sperror());
                    exit(1);
            }
     





            /* display confirmation if successful */
            if (error.service_error == NETMGT_SUCCESS) {
                    NETMGT_DBG("request succeeded. \n");
                    exit(0);
            }
     
            /* otherwise display error */
            NETMGT_DBG("request failed \n");
            NETMGT_DBG("service error code: %d\n", error.service_error);
            NETMGT_DBG("agent error code: %d ", error.agent_error);
            NETMGT_DBG("error message: %s \n", error.message);
     
            exit(0);
    }
     
    /*---------------------------------------------------------------------
     * unregister_results - unregister callback function before exiting
     * no return value
     *---------------------------------------------------------------------
     */
     
    static void
    unregister_results()
    {
            NETMGT_DBG("unregister_mycallback\n");
     
            /* tell the local portmapper to unregister the callback RPC service */
            if (!netmgt_unregister_callback(callback_prog, NETMGT_VERS))
                    NETMGT_DBG("can't unregister callback\n");
            exit(0);
    }
     




    [Top] [Prev] [Next] [Bottom]

    Copyright 1996 Sun Microsystems, Inc., 2550 Garcia Ave., Mtn. View, CA 94043-1100 USA. All Rights Reserved