Revert "Revert "and added files""
[bcm963xx.git] / userapps / opensource / net-snmp / agent / mibgroup / utilities / override.c
1 #ifdef BRCM_SNMP_WRITE_SUPPORT
2
3 /** allows overriding of a given oid with a new type and value */
4
5 #include <net-snmp/net-snmp-config.h>
6 #include <net-snmp/net-snmp-includes.h>
7 #include <net-snmp/agent/net-snmp-agent-includes.h>
8
9 #include "util_funcs.h"
10
11 typedef struct override_data_s {
12     int             type;
13     void           *value;
14     size_t          value_len;
15 } override_data;
16
17 /** @todo: (optionally) save values persistently when configured for
18  *  read-write */
19 int
20 override_handler(netsnmp_mib_handler *handler,
21                  netsnmp_handler_registration *reginfo,
22                  netsnmp_agent_request_info *reqinfo,
23                  netsnmp_request_info *requests)
24 {
25
26     override_data  *data = handler->myvoid;
27     if (!data) {
28         netsnmp_set_request_error(reqinfo, requests, SNMP_ERR_GENERR);
29         return SNMP_ERR_NOERROR;
30     }
31
32     switch (reqinfo->mode) {
33     case MODE_GET:
34         DEBUGMSGTL(("override", "overriding oid "));
35         DEBUGMSGOID(("override", requests->requestvb->name,
36                      requests->requestvb->name_length));
37         DEBUGMSG(("override", "\n"));
38         snmp_set_var_typed_value(requests->requestvb, data->type,
39                                  (u_char *) data->value, data->value_len);
40         break;
41
42     default:
43         snmp_log(LOG_ERR, "unsupported mode in override handler");
44         break;
45     }
46     return SNMP_ERR_NOERROR;
47 }
48
49 #define MALLOC_OR_DIE(x) \
50   thedata->value = malloc(x); \
51   thedata->value_len = x; \
52   if (!thedata->value) { \
53       free(thedata); \
54       config_perror("memory allocation failure"); \
55       return; \
56   }
57
58 void
59 netsnmp_parse_override(const char *token, char *line)
60 {
61     char           *cp;
62     char            buf[SNMP_MAXBUF];
63     int             readwrite = 0;
64     oid             oidbuf[MAX_OID_LEN];
65     size_t          oidbuf_len = sizeof(oidbuf);
66     int             type;
67     override_data  *thedata;
68     netsnmp_handler_registration *the_reg;
69
70     cp = copy_nword(line, buf, sizeof(buf) - 1);
71     if (strcmp(buf, "-rw") == 0) {
72         readwrite = 1;
73         cp = copy_nword(cp, buf, sizeof(buf) - 1);
74     }
75
76     if (!cp) {
77         config_perror("no oid specified");
78         return;
79     }
80
81     if (!snmp_parse_oid(buf, oidbuf, &oidbuf_len)) {
82         config_perror("illegal oid");
83         return;
84     }
85     cp = copy_nword(cp, buf, sizeof(buf) - 1);
86
87     if (!cp && strcmp(buf, "null") != 0) {
88         config_perror("no variable value specified");
89         return;
90     }
91
92     type = se_find_value_in_slist("asntypes", buf);
93     if (!type) {
94         config_perror("unknown type specified");
95         return;
96     }
97
98     if (cp)
99         copy_nword(cp, buf, sizeof(buf) - 1);
100     else
101         buf[0] = 0;
102
103     thedata = SNMP_MALLOC_TYPEDEF(override_data);
104     thedata->type = type;
105     if (!thedata) {
106         config_perror("memory allocation failure");
107         return;
108     }
109
110     switch (type) {
111     case ASN_INTEGER:
112         MALLOC_OR_DIE(sizeof(long));
113         *((long *) thedata->value) = strtol(buf, NULL, 0);
114         break;
115
116     case ASN_COUNTER:
117     case ASN_UNSIGNED:
118         MALLOC_OR_DIE(sizeof(u_long));
119         *((u_long *) thedata->value) = strtoul(buf, NULL, 0);
120         break;
121
122     case ASN_OCTET_STR:
123     case ASN_BIT_STR:
124         if (buf[0] == '0' && buf[1] == 'x') {
125             /*
126              * hex 
127              */
128             thedata->value_len =
129                 hex_to_binary2(buf + 2, strlen(buf) - 2,
130                                (char **) &thedata->value);
131         } else {
132             thedata->value = strdup(buf);
133             thedata->value_len = strlen(buf);
134         }
135         break;
136
137     case ASN_OBJECT_ID:
138         read_config_read_objid(buf, (oid **) & thedata->value,
139                                &thedata->value_len);
140         break;
141
142     case ASN_NULL:
143         thedata->value_len = 0;
144         break;
145
146     default:
147         config_perror("illegal/unsupported type specified");
148         return;
149     }
150
151     if (!thedata->value && thedata->type != ASN_NULL) {
152         config_perror("memory allocation failure");
153         free(thedata);
154         return;
155     }
156
157     the_reg = SNMP_MALLOC_TYPEDEF(netsnmp_handler_registration);
158     if (!the_reg) {
159         config_perror("memory allocation failure");
160         free(thedata);
161         return;
162     }
163
164     the_reg->priority = 255;
165     the_reg->modes = (readwrite) ? HANDLER_CAN_RWRITE : HANDLER_CAN_RONLY;
166     the_reg->handler =
167         netsnmp_create_handler("override", override_handler);
168     memdup((u_char **) & the_reg->rootoid, (const u_char *) oidbuf,
169            oidbuf_len * sizeof(oid));
170     the_reg->rootoid_len = oidbuf_len;
171     if (!the_reg->rootoid) {
172         config_perror("memory allocation failure");
173         free(thedata);
174         return;
175     }
176     the_reg->handler->myvoid = thedata;
177
178     if (netsnmp_register_instance(the_reg)) {
179         config_perror("oid registration failed within the agent");
180         SNMP_FREE(thedata->value);
181         free(thedata);
182         return;
183     }
184 }
185
186
187 void
188 init_override(void)
189 {
190
191     snmpd_register_config_handler("override", netsnmp_parse_override, NULL,     /* XXX: free func */
192                                   "[-rw] mibnode type value");
193 }
194 #endif /* BRCM_SNMP_WRITE_SUPPORT */