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
, " [-Ce] createView 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
);