2 * snmpvacm.c - send snmp SET requests to a network entity to change the
6 #include <net-snmp/net-snmp-config.h>
19 #include <sys/types.h>
21 #include <netinet/in.h>
25 #if TIME_WITH_SYS_TIME
27 # include <sys/timeb.h>
29 # include <sys/time.h>
34 # include <sys/time.h>
40 #include <sys/select.h>
49 #include <arpa/inet.h>
52 #include <net-snmp/net-snmp-includes.h>
54 int main(int, char **);
56 #define CMD_CREATESEC2GROUP_NAME "createSec2Group"
57 #define CMD_CREATESEC2GROUP 1
58 #define CMD_DELETESEC2GROUP_NAME "deleteSec2Group"
59 #define CMD_DELETESEC2GROUP 2
60 #define CMD_CREATEACCESS_NAME "createAccess"
61 #define CMD_CREATEACCESS 3
62 #define CMD_DELETEACCESS_NAME "deleteAccess"
63 #define CMD_DELETEACCESS 4
64 #define CMD_CREATEVIEW_NAME "createView"
65 #define CMD_CREATEVIEW 5
66 #define CMD_DELETEVIEW_NAME "deleteView"
67 #define CMD_DELETEVIEW 6
71 static const char *successNotes[CMD_NUM] = {
72 "Sec2group successfully created.",
73 "Sec2group successfully deleted.",
74 "Access successfully created.",
75 "Access successfully deleted.",
76 "View successfully created.",
77 "View successfully deleted."
80 #define SEC2GROUP_OID_LEN 11
81 #define ACCESS_OID_LEN 11
82 #define VIEW_OID_LEN 12
84 static oid vacmGroupName[MAX_OID_LEN] =
85 { 1, 3, 6, 1, 6, 3, 16, 1, 2, 1, 3 },
86 vacmSec2GroupStorageType[MAX_OID_LEN] = {
87 1, 3, 6, 1, 6, 3, 16, 1, 2, 1, 4}, vacmSec2GroupStatus[MAX_OID_LEN] = {
88 1, 3, 6, 1, 6, 3, 16, 1, 2, 1, 5}, vacmAccessContextMatch[MAX_OID_LEN] = {
89 1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 4}, vacmAccessReadViewName[MAX_OID_LEN] = {
90 1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 5}, vacmAccessWriteViewName[MAX_OID_LEN] = {
91 1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 6}, vacmAccessNotifyViewName[MAX_OID_LEN] = {
92 1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 7}, vacmAccessStorageType[MAX_OID_LEN] = {
93 1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 8}, vacmAccessStatus[MAX_OID_LEN] = {
94 1, 3, 6, 1, 6, 3, 16, 1, 4, 1, 9}, vacmViewTreeFamilyMask[MAX_OID_LEN] = {
95 1, 3, 6, 1, 6, 3, 16, 1, 5, 2, 1, 3}, vacmViewTreeFamilyType[MAX_OID_LEN] = {
96 1, 3, 6, 1, 6, 3, 16, 1, 5, 2, 1, 4},
97 vacmViewTreeFamilyStorageType[MAX_OID_LEN] = {
98 1, 3, 6, 1, 6, 3, 16, 1, 5, 2, 1, 5},
99 vacmViewTreeFamilyStatus[MAX_OID_LEN] = {
100 1, 3, 6, 1, 6, 3, 16, 1, 5, 2, 1, 6}
104 int viewTreeFamilyType = 1;
109 fprintf(stderr, "Usage: snmpvacm ");
110 snmp_parse_args_usage(stderr);
111 fprintf(stderr, " COMMAND\n\n");
112 snmp_parse_args_descriptions(stderr);
113 fprintf(stderr, "\nsnmpvacm commands:\n");
115 " createAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL CONTEXTMATCH READVIEWNAME WRITEVIEWNAME NOTIFYVIEWNAME\n");
117 " deleteAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL\n");
118 fprintf(stderr, " createSec2Group MODEL SECURITYNAME GROUPNAME\n");
119 fprintf(stderr, " deleteSec2Group MODEL SECURITYNAME\n");
120 fprintf(stderr, " createView [-Ce] NAME SUBTREE MASK\n");
121 fprintf(stderr, " deleteView NAME SUBTREE\n");
126 access_oid(oid * it, size_t * len, const char *groupName,
127 const char *prefix, int model, int level)
131 int itIndex = ACCESS_OID_LEN;
133 *len = itIndex + 4 + +strlen(groupName);
135 it[itIndex++] = strlen(groupName);
136 for (i = 0; i < (int) strlen(groupName); i++)
137 it[itIndex++] = groupName[i];
140 *len += strlen(prefix);
141 it[itIndex++] = strlen(prefix);
142 for (i = 0; i < (int) strlen(prefix); i++)
143 it[itIndex++] = prefix[i];
147 it[itIndex++] = model;
148 it[itIndex++] = level;
153 sec2group_oid(oid * it, size_t * len, int model, const char *name)
157 int itIndex = SEC2GROUP_OID_LEN;
159 *len = itIndex + 2 + strlen(name);
161 it[itIndex++] = model;
163 it[itIndex++] = strlen(name);
164 for (i = 0; i < (int) strlen(name); i++)
165 it[itIndex++] = name[i];
169 view_oid(oid * it, size_t * len, const char *viewName, char *viewSubtree)
172 oid c_oid[SPRINT_MAX_LEN];
173 size_t c_oid_length = SPRINT_MAX_LEN;
175 int itIndex = VIEW_OID_LEN;
177 if (!read_objid(viewSubtree, c_oid, &c_oid_length)) {
178 printf("Error parsing subtree\n");
182 *len = itIndex + 2 + strlen(viewName) + c_oid_length;
184 it[itIndex++] = strlen(viewName);
185 for (i = 0; i < (int) strlen(viewName); i++)
186 it[itIndex++] = viewName[i];
189 it[itIndex++] = c_oid_length;
190 for (i = 0; i < (int) c_oid_length; i++)
191 it[itIndex++] = c_oid[i];
194 * sprint_objid(c_oid, it, *len);
199 optProc(int argc, char *const *argv, int opt)
206 viewTreeFamilyType = 2;
211 "Unknown flag passed to -C: %c\n", optarg[-1]);
221 main(int argc, char *argv[])
223 netsnmp_session session, *ss;
224 netsnmp_pdu *pdu = NULL, *response = NULL;
226 netsnmp_variable_list *vars;
232 int current_name = 0;
233 int current_type = 0;
234 int current_value = 0;
238 oid name[MAX_OID_LEN];
245 int secModel, secLevel, contextMatch, val, i = 0;
246 char *mask, *groupName, *prefix;
247 u_char viewMask[VACMSTRINGLEN];
251 * get the common command line arguments
253 switch (arg = snmp_parse_args(argc, argv, &session, "C:", optProc)) {
267 * open an SNMP session
270 * Note: this wil obtain the engineID needed below
272 ss = snmp_open(&session);
275 * diagnose snmp_open errors with the input netsnmp_session pointer
277 snmp_sess_perror("snmpvacm", &session);
282 * create PDU for SET request and add object names and values to request
284 pdu = snmp_pdu_create(SNMP_MSG_SET);
287 fprintf(stderr, "Please specify a opreation to perform.\n");
292 if (strcmp(argv[arg], CMD_DELETEVIEW_NAME) == 0)
294 * deleteView: delete a view
296 * deleteView NAME SUBTREE
300 if (++arg + 2 != argc) {
301 fprintf(stderr, "You must specify the view to delete\n");
306 command = CMD_DELETEVIEW;
307 name_length = VIEW_OID_LEN;
308 view_oid(vacmViewTreeFamilyStatus, &name_length, argv[arg],
310 longvar = RS_DESTROY;
311 snmp_pdu_add_variable(pdu, vacmViewTreeFamilyStatus, name_length,
312 ASN_INTEGER, (u_char *) & longvar,
314 } else if (strcmp(argv[arg], CMD_CREATEVIEW_NAME) == 0)
316 * createView: create a view
318 * createView NAME SUBTREE MASK
322 if (++arg + 3 > argc) {
323 fprintf(stderr, "You must specify name, subtree and mask\n");
327 command = CMD_CREATEVIEW;
328 name_length = VIEW_OID_LEN;
329 view_oid(vacmViewTreeFamilyStatus, &name_length, argv[arg],
331 longvar = RS_CREATEANDGO;
332 snmp_pdu_add_variable(pdu, vacmViewTreeFamilyStatus, name_length,
333 ASN_INTEGER, (u_char *) & longvar,
339 mask = argv[arg + 2];
340 for (mask = strtok(mask, ".:"); mask; mask = strtok(NULL, ".:")) {
341 if (i >= sizeof(viewMask)) {
342 printf("MASK too long\n");
345 if (sscanf(mask, "%x", &val) == 0) {
346 printf("invalid MASK\n");
352 view_oid(vacmViewTreeFamilyMask, &name_length, argv[arg],
354 snmp_pdu_add_variable(pdu, vacmViewTreeFamilyMask, name_length,
355 ASN_OCTET_STR, viewMask, i);
357 view_oid(vacmViewTreeFamilyType, &name_length, argv[arg],
359 snmp_pdu_add_variable(pdu, vacmViewTreeFamilyType, name_length,
360 ASN_INTEGER, (u_char *) & viewTreeFamilyType,
361 sizeof(viewTreeFamilyType));
363 } else if (strcmp(argv[arg], CMD_DELETESEC2GROUP_NAME) == 0)
365 * deleteSec2Group: delete security2group
367 * deleteSec2Group MODEL SECURITYNAME
371 if (++arg + 2 != argc) {
372 fprintf(stderr, "You must specify the sec2group to delete\n");
377 command = CMD_DELETESEC2GROUP;
378 name_length = SEC2GROUP_OID_LEN;
379 if (sscanf(argv[arg], "%d", &secModel) == 0) {
380 printf("invalid security model\n");
384 sec2group_oid(vacmSec2GroupStatus, &name_length, secModel,
386 longvar = RS_DESTROY;
387 snmp_pdu_add_variable(pdu, vacmSec2GroupStatus, name_length,
388 ASN_INTEGER, (u_char *) & longvar,
390 } else if (strcmp(argv[arg], CMD_CREATESEC2GROUP_NAME) == 0)
392 * createSec2Group: create a security2group
394 * createSec2Group MODEL SECURITYNAME GROUPNAME
398 if (++arg + 3 != argc) {
400 "You must specify model, security name and group name\n");
405 command = CMD_CREATESEC2GROUP;
406 name_length = SEC2GROUP_OID_LEN;
407 if (sscanf(argv[arg], "%d", &secModel) == 0) {
408 printf("invalid security model\n");
412 sec2group_oid(vacmSec2GroupStatus, &name_length, secModel,
414 longvar = RS_CREATEANDGO;
415 snmp_pdu_add_variable(pdu, vacmSec2GroupStatus, name_length,
416 ASN_INTEGER, (u_char *) & longvar,
418 sec2group_oid(vacmGroupName, &name_length, secModel,
420 snmp_pdu_add_variable(pdu, vacmGroupName, name_length,
421 ASN_OCTET_STR, (u_char *) argv[arg + 2],
422 strlen(argv[arg + 2]));
423 } else if (strcmp(argv[arg], CMD_DELETEACCESS_NAME) == 0)
425 * deleteAccess: delete access entry
427 * deleteAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL
431 if (++arg + 3 > argc) {
433 "You must specify the access entry to delete\n");
438 command = CMD_DELETEACCESS;
439 name_length = ACCESS_OID_LEN;
440 groupName = argv[arg];
442 prefix = argv[++arg];
446 if (sscanf(argv[arg + 1], "%d", &secModel) == 0) {
447 printf("invalid security model\n");
451 if (sscanf(argv[arg + 2], "%d", &secLevel) == 0) {
452 printf("invalid security level\n");
456 access_oid(vacmAccessStatus, &name_length, groupName, prefix,
458 longvar = RS_DESTROY;
459 snmp_pdu_add_variable(pdu, vacmAccessStatus, name_length,
460 ASN_INTEGER, (u_char *) & longvar,
462 } else if (strcmp(argv[arg], CMD_CREATEACCESS_NAME) == 0)
464 * createAccess: create access entry
466 * createAccess GROUPNAME [CONTEXTPREFIX] SECURITYMODEL SECURITYLEVEL CONTEXTMATCH READVIEWNAME WRITEVIEWNAME NOTIFYVIEWNAME
470 if (++arg + 7 > argc) {
472 "You must specify the access entry to create\n");
477 command = CMD_CREATEACCESS;
478 name_length = ACCESS_OID_LEN;
479 groupName = argv[arg];
481 prefix = argv[++arg];
485 if (sscanf(argv[arg + 1], "%d", &secModel) == 0) {
486 printf("invalid security model\n");
490 if (sscanf(argv[arg + 2], "%d", &secLevel) == 0) {
491 printf("invalid security level\n");
495 access_oid(vacmAccessStatus, &name_length, groupName, prefix,
497 longvar = RS_CREATEANDGO;
498 snmp_pdu_add_variable(pdu, vacmAccessStatus, name_length,
499 ASN_INTEGER, (u_char *) & longvar,
502 access_oid(vacmAccessContextMatch, &name_length, groupName, prefix,
504 if (sscanf(argv[arg + 3], "%d", &contextMatch) == 0) {
505 printf("invalid contextMatch\n");
509 snmp_pdu_add_variable(pdu, vacmAccessContextMatch, name_length,
510 ASN_INTEGER, (u_char *) & contextMatch,
511 sizeof(contextMatch));
513 access_oid(vacmAccessReadViewName, &name_length, groupName, prefix,
515 snmp_pdu_add_variable(pdu, vacmAccessReadViewName, name_length,
516 ASN_OCTET_STR, (u_char *) argv[arg + 4],
517 strlen(argv[arg + 4]));
519 access_oid(vacmAccessWriteViewName, &name_length, groupName,
520 prefix, secModel, secLevel);
521 snmp_pdu_add_variable(pdu, vacmAccessWriteViewName, name_length,
522 ASN_OCTET_STR, (u_char *) argv[arg + 5],
523 strlen(argv[arg + 5]));
525 access_oid(vacmAccessNotifyViewName, &name_length, groupName,
526 prefix, secModel, secLevel);
527 snmp_pdu_add_variable(pdu, vacmAccessNotifyViewName, name_length,
528 ASN_OCTET_STR, (u_char *) argv[arg + 6],
529 strlen(argv[arg + 6]));
531 printf("Unknown command\n");
539 status = snmp_synch_response(ss, pdu, &response);
540 if (status == STAT_SUCCESS) {
542 if (response->errstat == SNMP_ERR_NOERROR) {
543 fprintf(stderr, "%s\n", successNotes[command - 1]);
545 fprintf(stderr, "Error in packet.\nReason: %s\n",
546 snmp_errstring(response->errstat));
547 if (response->errindex != 0){
549 struct variable_list *vars = response->variables;
550 fprintf(stderr, "Failed object: ");
551 for(count = 1; vars && (count != response->errindex);
552 vars = vars->next_variable, count++)
555 fprint_objid(stderr, vars->name, vars->name_length);
556 fprintf(stderr, "\n");
561 } else if (status == STAT_TIMEOUT) {
562 fprintf(stderr, "Timeout: No Response from %s\n",
566 snmp_sess_perror("snmpset", ss);
571 snmp_free_pdu(response);