4 * Operations to generate NET-SNMP mib module implementation code.
6 * Copyright (c) 1999 Frank Strauss, Technical University of Braunschweig.
7 * Copyright (c) 1999 J. Schoenwaelder, Technical University of Braunschweig.
9 * See the file "COPYING" for information on usage and redistribution
10 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 * @(#) $Id: dump-netsnmp.c 8090 2008-04-18 12:56:29Z strauss $
17 * - assume that we build a dynamic loadable module
18 * - update to 4.X version of the UCD API
19 * - generate #defines for deprecated and obsolete objects
20 * - generate stub codes for the various functions
21 * - generate type and range checking code
41 static int noMgrStubs = 0;
42 static int noAgtStubs = 0;
45 static char *getAccessString(SmiAccess access)
47 if (access == SMI_ACCESS_READ_WRITE) {
49 } else if (access == SMI_ACCESS_READ_ONLY) {
57 static char *getBaseTypeString(SmiBasetype basetype)
60 case SMI_BASETYPE_UNKNOWN:
62 case SMI_BASETYPE_POINTER:
64 case SMI_BASETYPE_INTEGER32:
65 case SMI_BASETYPE_ENUM:
67 case SMI_BASETYPE_OCTETSTRING:
68 case SMI_BASETYPE_BITS:
69 return "ASN_OCTET_STR";
70 case SMI_BASETYPE_OBJECTIDENTIFIER:
71 return "ASN_OBJECT_ID";
72 case SMI_BASETYPE_UNSIGNED32:
74 case SMI_BASETYPE_INTEGER64:
76 case SMI_BASETYPE_UNSIGNED64:
78 case SMI_BASETYPE_FLOAT32:
79 case SMI_BASETYPE_FLOAT64:
80 case SMI_BASETYPE_FLOAT128:
89 static char* translate(char *m)
95 for (i = 0; s[i]; i++) {
96 if (s[i] == '-') s[i] = '_';
104 static char* translateUpper(char *m)
110 for (i = 0; s[i]; i++) {
111 if (s[i] == '-') s[i] = '_';
112 if (islower((int) s[i])) {
113 s[i] = toupper(s[i]);
122 static char* translateLower(char *m)
128 for (i = 0; s[i]; i++) {
129 if (s[i] == '-') s[i] = '_';
130 if (isupper((int) s[i])) {
131 s[i] = tolower(s[i]);
140 static char* translateFileName(char *m)
146 for (i = 0; s[i]; i++) {
147 if (s[i] == '_') s[i] = '-';
148 if (isupper((int) s[i])) {
149 s[i] = tolower(s[i]);
158 static FILE * createFile(char *name, char *suffix)
163 fullname = xmalloc(strlen(name) + (suffix ? strlen(suffix) : 0) + 2);
164 strcpy(fullname, name);
166 strcat(fullname, suffix);
168 if (!access(fullname, R_OK)) {
169 fprintf(stderr, "smidump: %s already exists\n", fullname);
173 f = fopen(fullname, "w");
175 fprintf(stderr, "smidump: cannot open %s for writing: ", fullname);
186 static int isGroup(SmiNode *smiNode)
190 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
194 for (childNode = smiGetFirstChildNode(smiNode);
196 childNode = smiGetNextChildNode(childNode)) {
197 if (childNode->nodekind == SMI_NODEKIND_SCALAR) {
207 static int isAccessible(SmiNode *groupNode)
212 for (smiNode = smiGetFirstChildNode(groupNode);
214 smiNode = smiGetNextChildNode(smiNode)) {
215 if ((smiNode->nodekind == SMI_NODEKIND_SCALAR
216 || smiNode->nodekind == SMI_NODEKIND_COLUMN)
217 && (smiNode->access == SMI_ACCESS_READ_ONLY
218 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
228 static void printHeaderTypedef(FILE *f, SmiModule *smiModule,
233 char *cModuleName, *cGroupName, *cName;
234 unsigned minSize, maxSize;
236 cModuleName = translateLower(smiModule->name);
237 cGroupName = translate(groupNode->name);
241 " * C type definitions for %s::%s.\n"
243 smiModule->name, groupNode->name);
245 fprintf(f, "typedef struct %s {\n", cGroupName);
247 for (smiNode = smiGetFirstChildNode(groupNode);
249 smiNode = smiGetNextChildNode(smiNode)) {
250 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
252 && (smiNode->access == SMI_ACCESS_READ_ONLY
253 || smiNode->access == SMI_ACCESS_READ_WRITE)
256 smiType = smiGetNodeType(smiNode);
261 cName = translate(smiNode->name);
262 switch (smiType->basetype) {
263 case SMI_BASETYPE_OBJECTIDENTIFIER:
264 maxSize = smiGetMaxSize(smiType);
265 minSize = smiGetMinSize(smiType);
267 " uint32_t *%s;\n", cName);
268 if (maxSize != minSize) {
270 " size_t _%sLength;\n", cName);
273 case SMI_BASETYPE_OCTETSTRING:
274 case SMI_BASETYPE_BITS:
275 maxSize = smiGetMaxSize(smiType);
276 minSize = smiGetMinSize(smiType);
278 " u_char *%s;\n", cName);
279 if (maxSize != minSize) {
281 " size_t _%sLength;\n", cName);
284 case SMI_BASETYPE_ENUM:
285 case SMI_BASETYPE_INTEGER32:
287 " int32_t *%s;\n", cName);
289 case SMI_BASETYPE_UNSIGNED32:
291 " uint32_t *%s;\n", cName);
293 case SMI_BASETYPE_INTEGER64:
295 " int64_t *%s; \n", cName);
297 case SMI_BASETYPE_UNSIGNED64:
299 " uint64_t *%s; \n", cName);
303 " /* ?? */ __%s; \n", cName);
311 " void *_clientData;\t\t"
312 "/* pointer to client data structure */\n");
313 if (groupNode->nodekind == SMI_NODEKIND_ROW) {
314 fprintf(f, " struct %s *_nextPtr;\t"
315 "/* pointer to next table entry */\n", cGroupName);
318 "\n /* private space to hold actual values */\n\n");
320 for (smiNode = smiGetFirstChildNode(groupNode);
322 smiNode = smiGetNextChildNode(smiNode)) {
323 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
325 && (smiNode->access == SMI_ACCESS_READ_ONLY
326 || smiNode->access == SMI_ACCESS_READ_WRITE)
329 smiType = smiGetNodeType(smiNode);
334 cName = translate(smiNode->name);
335 switch (smiType->basetype) {
336 case SMI_BASETYPE_OBJECTIDENTIFIER:
337 maxSize = smiGetMaxSize(smiType);
339 " uint32_t __%s[%u];\n", cName, maxSize);
341 case SMI_BASETYPE_OCTETSTRING:
342 case SMI_BASETYPE_BITS:
343 maxSize = smiGetMaxSize(smiType);
345 " u_char __%s[%u];\n", cName, maxSize);
347 case SMI_BASETYPE_ENUM:
348 case SMI_BASETYPE_INTEGER32:
350 " int32_t __%s;\n", cName);
352 case SMI_BASETYPE_UNSIGNED32:
354 " uint32_t __%s;\n", cName);
356 case SMI_BASETYPE_INTEGER64:
358 " int64_t __%s; \n", cName);
360 case SMI_BASETYPE_UNSIGNED64:
362 " uint64_t __%s; \n", cName);
366 " /* ?? */ __%s; \n", cName);
373 fprintf(f, "} %s_t;\n\n", cGroupName);
377 " * C manager interface stubs for %s::%s.\n"
379 smiModule->name, groupNode->name);
381 fprintf(f, "extern int\n"
382 "%s_mgr_get_%s(struct snmp_session *s, %s_t **%s);\n",
383 cModuleName, cGroupName, cGroupName, cGroupName);
388 " * C agent interface stubs for %s::%s.\n"
390 smiModule->name, groupNode->name);
392 fprintf(f, "extern int\n"
393 "%s_agt_read_%s(%s_t *%s);\n",
394 cModuleName, cGroupName, cGroupName, cGroupName);
395 fprintf(f, "extern int\n"
396 "%s_agt_register_%s();\n\n",
397 cModuleName, cGroupName);
404 static void printHeaderTypedefs(FILE *f, SmiModule *smiModule)
411 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
413 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
414 if (isGroup(smiNode) && isAccessible(smiNode)) {
416 printHeaderTypedef(f, smiModule, smiNode);
426 * Should this go into the agent implementation module?
428 cModuleName = translateLower(smiModule->name);
429 fprintf(f, "typedef struct %s {\n", cModuleName);
430 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
432 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
433 if (isGroup(smiNode) && isAccessible(smiNode)) {
434 cSmiNodeName = translate(smiNode->name);
435 if (smiNode->nodekind == SMI_NODEKIND_ROW) {
436 fprintf(f, " %s_t\t*%s;\n", cSmiNodeName, cSmiNodeName);
438 fprintf(f, " %s_t\t%s;\n", cSmiNodeName, cSmiNodeName);
443 fprintf(f, "} %s_t;\n\n", cModuleName);
450 static void dumpHeader(SmiModule *smiModule, char *baseName)
456 pModuleName = translateUpper(smiModule->name);
458 f = createFile(baseName, ".h");
465 " * This C header file has been generated by smidump "
466 SMI_VERSION_STRING ".\n"
467 " * It is intended to be used with the NET-SNMP package.\n"
469 " * This header is derived from the %s module.\n"
471 " */\n\n", smiModule->name);
473 fprintf(f, "#ifndef _%s_H_\n", pModuleName);
474 fprintf(f, "#define _%s_H_\n\n", pModuleName);
476 fprintf(f, "#include <stdlib.h>\n\n");
479 "#ifdef HAVE_STDINT_H\n"
480 "#include <stdint.h>\n"
483 printHeaderTypedefs(f, smiModule);
487 " * Initialization function:\n"
489 cModuleName = translateLower(smiModule->name);
490 fprintf(f, "void %s_agt_init(void);\n\n", cModuleName);
493 fprintf(f, "#endif /* _%s_H_ */\n", pModuleName);
501 static void printAgtReadMethodDecls(FILE *f, SmiModule *smiModule)
506 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
508 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
509 if (isGroup(smiNode) && isAccessible(smiNode)) {
514 " * Forward declaration of read methods for groups of scalars and tables:\n"
518 "static unsigned char *\nread_%s_stub(struct variable *,"
519 " oid *, size_t *, int, size_t *, WriteMethod **);\n",
531 static void printAgtWriteMethodDecls(FILE *f, SmiModule *smiModule)
536 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
538 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
539 if (smiNode->access == SMI_ACCESS_READ_WRITE) {
544 " * Forward declaration of write methods for writable objects:\n"
548 "static int\nwrite_%s_stub(int,"
549 " u_char *, u_char, int, u_char *, oid *, int);\n",
561 static void printAgtDefinesGroup(FILE *f, SmiNode *groupNode, int cnt)
563 char *cName, *cGroupName;
572 " * Definitions of tags that are used internally to read/write\n"
573 " * the selected object type. These tags should be unique.\n"
577 cGroupName = translate(groupNode->name);
579 for (smiNode = smiGetFirstChildNode(groupNode);
581 smiNode = smiGetNextChildNode(smiNode)) {
582 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
583 && (smiNode->access == SMI_ACCESS_READ_ONLY
584 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
586 cName = translateUpper(smiNode->name);
587 fprintf(f, "#define %-32s %d\n", cName,
588 smiNode->oid[smiNode->oidlen-1]);
595 fprintf(f, "static oid %s_base[] = {", cGroupName);
596 for (i = 0; i < groupNode->oidlen; i++) {
597 fprintf(f, "%s%d", i ? ", " : "", groupNode->oid[i]);
599 fprintf(f, "};\n\n");
600 fprintf(f, "struct variable %s_variables[] = {\n", cGroupName);
601 for (smiNode = smiGetFirstChildNode(groupNode);
603 smiNode = smiGetNextChildNode(smiNode)) {
604 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
605 && (smiNode->access == SMI_ACCESS_READ_ONLY
606 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
607 smiType = smiGetNodeType(smiNode);
611 cName = translateUpper(smiNode->name);
612 fprintf(f, " { %s, %s, %s, read_%s_stub, %d, {%d} },\n",
613 cName, getBaseTypeString(smiType->basetype),
614 getAccessString(smiNode->access),
615 cGroupName, 1, smiNode->oid[smiNode->oidlen-1]);
619 fprintf(f, "};\n\n");
627 static void printAgtDefines(FILE *f, SmiModule *smiModule)
632 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
634 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
635 if (isGroup(smiNode)) {
636 printAgtDefinesGroup(f, smiNode, ++cnt);
647 static void printAgtRegister(FILE *f, SmiNode *groupNode, int cnt)
653 for (smiNode = smiGetFirstChildNode(groupNode);
655 smiNode = smiGetNextChildNode(smiNode)) {
656 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
657 && (smiNode->access == SMI_ACCESS_READ_ONLY
658 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
667 " * Registration functions for the various MIB groups.\n"
671 cGroupName = translate(groupNode->name);
673 fprintf(f, "int register_%s()\n{\n", cGroupName);
675 " return register_mib(\"%s\",\n"
677 " sizeof(struct variable),\n"
678 " sizeof(%s_variables)/sizeof(struct variable),\n"
680 " sizeof(%s_base)/sizeof(oid));\n",
681 cGroupName, cGroupName, cGroupName, cGroupName, cGroupName);
682 fprintf(f, "};\n\n");
689 static void printAgtInit(FILE *f, SmiModule *smiModule)
694 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
696 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
697 if (isGroup(smiNode)) {
698 printAgtRegister(f, smiNode, ++cnt);
709 static void printAgtReadMethod(FILE *f, SmiNode *groupNode)
713 char *cName, *sName, *lName;
715 sName = translate(groupNode->name);
718 "static unsigned char *\nread_%s_stub(struct variable *vp,\n"
722 " size_t *var_len,\n"
723 " WriteMethod **write_method)\n"
726 fprintf(f, " static %s_t %s;\n\n", sName, sName);
728 smiNode = smiGetFirstChildNode(groupNode);
729 if (smiNode && smiNode->nodekind == SMI_NODEKIND_SCALAR) {
731 " /* check whether the instance identifier is valid */\n"
733 " if (header_generic(vp, name, length, exact, var_len,\n"
734 " write_method) == MATCH_FAILED) {\n"
741 " /* call the user supplied function to retrieve values */\n"
747 " /* return the current value of the variable */\n"
749 " switch (vp->magic) {\n"
752 for (smiNode = smiGetFirstChildNode(groupNode);
754 smiNode = smiGetNextChildNode(smiNode)) {
755 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
756 && (smiNode->access == SMI_ACCESS_READ_ONLY
757 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
758 cName = translateUpper(smiNode->name);
759 lName = translate(smiNode->name);
760 smiType = smiGetNodeType(smiNode);
764 fprintf(f, " case %s:\n", cName);
765 switch (smiType->basetype) {
766 case SMI_BASETYPE_OBJECTIDENTIFIER:
768 " *var_len = %s._%sLength;\n"
769 " return (unsigned char *) %s.%s;\n",
770 sName, lName, sName, lName);
772 case SMI_BASETYPE_OCTETSTRING:
773 case SMI_BASETYPE_BITS:
775 " *var_len = %s._%sLength;\n"
776 " return (unsigned char *) %s.%s;\n",
777 sName, lName, sName, lName);
779 case SMI_BASETYPE_ENUM:
780 case SMI_BASETYPE_INTEGER32:
781 case SMI_BASETYPE_UNSIGNED32:
783 " return (unsigned char *) &%s.%s;\n",
788 " /* add code to return the value here */\n");
798 " ERROR_MSG(\"\");\n"
810 static void printAgtReadMethods(FILE *f, SmiModule *smiModule)
815 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
817 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
818 if (isGroup(smiNode) && isAccessible(smiNode)) {
823 " * Read methods for groups of scalars and tables:\n"
826 printAgtReadMethod(f, smiNode);
837 static void printAgtWriteMethods(FILE *f, SmiModule *smiModule)
842 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
844 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
845 if (smiNode->access == SMI_ACCESS_READ_WRITE) {
850 " * Forward declaration of write methods for writable objects:\n"
854 "static int\nwrite_%s_stub(int action,\n"
855 " u_char *var_val,\n"
856 " u_char var_val_type,\n"
857 " int var_val_len,\n"
861 "{\n", smiNode->name);
863 " return SNMP_ERR_NOERROR;\n"
875 static void dumpAgtStub(SmiModule *smiModule, char *baseName)
877 char *stubModuleName;
880 stubModuleName = xmalloc(strlen(baseName) + 10);
881 strcpy(stubModuleName, baseName);
882 strcat(stubModuleName, "-agt-stub");
884 f = createFile(stubModuleName, ".c");
886 xfree(stubModuleName);
892 " * This C file has been generated by smidump "
893 SMI_VERSION_STRING ".\n"
894 " * It is intended to be used with the NET-SNMP agent library.\n"
896 " * This C file is derived from the %s module.\n"
898 " */\n\n", smiModule->name );
901 "#include <stdio.h>\n"
902 "#include <string.h>\n"
903 "#include <malloc.h>\n"
905 "#include \"%s.h\"\n"
907 "#include <ucd-snmp/asn1.h>\n"
908 "#include <ucd-snmp/snmp.h>\n"
909 "#include <ucd-snmp/snmp_api.h>\n"
910 "#include <ucd-snmp/snmp_impl.h>\n"
911 "#include <ucd-snmp/snmp_vars.h>\n"
915 printAgtReadMethodDecls(f, smiModule);
916 printAgtWriteMethodDecls(f, smiModule);
917 printAgtDefines(f, smiModule);
918 printAgtInit(f, smiModule);
920 printAgtReadMethods(f, smiModule);
921 printAgtWriteMethods(f, smiModule);
924 xfree(stubModuleName);
929 static void printMgrOidDefinitions(FILE *f, SmiModule *smiModule)
935 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
937 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
938 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
939 && smiNode->access != SMI_ACCESS_NOTIFY) {
940 cName = translate(smiNode->name);
941 fprintf(f, "static oid %s[] = {", cName);
942 for (i = 0; i < smiNode->oidlen; i++) {
943 fprintf(f, "%s%u", i ? ", " : "", smiNode->oid[i]);
954 static void printMgrGetScalarAssignement(FILE *f, SmiNode *groupNode)
958 char *cGroupName, *cName;
959 unsigned maxSize, minSize;
961 cGroupName = translate(groupNode->name);
963 for (smiNode = smiGetFirstChildNode(groupNode);
965 smiNode = smiGetNextChildNode(smiNode)) {
966 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
967 && (smiNode->access == SMI_ACCESS_READ_ONLY
968 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
970 smiType = smiGetNodeType(smiNode);
975 cName = translate(smiNode->name);
977 " if (vars->name_length > sizeof(%s)/sizeof(oid)\n"
978 " && memcmp(vars->name, %s, sizeof(%s)) == 0) {\n",
979 cName, cName, cName);
980 switch (smiType->basetype) {
981 case SMI_BASETYPE_INTEGER32:
982 case SMI_BASETYPE_UNSIGNED32:
983 case SMI_BASETYPE_ENUM:
985 " (*%s)->__%s = *vars->val.integer;\n"
986 " (*%s)->%s = &((*%s)->__%s);\n",
988 cGroupName, cName, cGroupName, cName);
990 case SMI_BASETYPE_OCTETSTRING:
991 case SMI_BASETYPE_BITS:
992 maxSize = smiGetMaxSize(smiType);
993 minSize = smiGetMinSize(smiType);
995 " memcpy((*%s)->__%s, vars->val.string, vars->val_len);\n",
997 if (minSize != maxSize) {
999 " (*%s)->_%sLength = vars->val_len;\n",
1003 " (*%s)->%s = (*%s)->__%s;\n",
1004 cGroupName, cName, cGroupName, cName);
1006 case SMI_BASETYPE_OBJECTIDENTIFIER:
1022 static void printMgrGetMethod(FILE *f, SmiModule *smiModule,
1026 char *cModuleName, *cGroupName;
1028 cModuleName = translateLower(smiModule->name);
1029 cGroupName = translate(groupNode->name);
1032 "int %s_mgr_get_%s(struct snmp_session *s, %s_t **%s)\n"
1034 " struct snmp_session *peer;\n"
1035 " struct snmp_pdu *request, *response;\n"
1036 " struct variable_list *vars;\n"
1039 cModuleName, cGroupName, cGroupName, cGroupName);
1042 " request = snmp_pdu_create(SNMP_MSG_GETNEXT);\n");
1044 for (smiNode = smiGetFirstChildNode(groupNode);
1046 smiNode = smiGetNextChildNode(smiNode)) {
1047 if (smiNode->nodekind & (SMI_NODEKIND_COLUMN | SMI_NODEKIND_SCALAR)
1048 && (smiNode->access == SMI_ACCESS_READ_ONLY
1049 || smiNode->access == SMI_ACCESS_READ_WRITE)) {
1051 " snmp_add_null_var(request, %s, sizeof(%s)/sizeof(oid));\n",
1052 smiNode->name, smiNode->name);
1058 " peer = snmp_open(s);\n"
1060 " snmp_free_pdu(request);\n"
1064 " status = snmp_synch_response(peer, request, &response);\n"
1065 " if (status != STAT_SUCCESS) {\n"
1066 " if (response) snmp_free_pdu(response);\n"
1067 " snmp_close(peer);\n"
1072 /* generate code for error checking and handling */
1075 " *%s = (%s_t *) malloc(sizeof(%s_t));\n"
1077 " if (response) snmp_free_pdu(response);\n"
1078 " snmp_close(peer);\n"
1082 cGroupName, cGroupName, cGroupName, cGroupName);
1085 " for (vars = response->variables; vars; vars = vars->next_variable) {\n");
1086 printMgrGetScalarAssignement(f, groupNode);
1093 if (response->errstat != SNMP_ERR_NOERROR) {
1097 /* copy to data structures */
1104 " if (response) snmp_free_pdu(response);\n"
1106 " if (snmp_close(peer) == 0) {\n"
1120 static void printMgrGetMethods(FILE *f, SmiModule *smiModule)
1125 for (smiNode = smiGetFirstNode(smiModule, SMI_NODEKIND_ANY);
1127 smiNode = smiGetNextNode(smiNode, SMI_NODEKIND_ANY)) {
1128 if (isGroup(smiNode) && isAccessible(smiNode)) {
1130 printMgrGetMethod(f, smiModule, smiNode);
1141 static void dumpMgrStub(SmiModule *smiModule, char *baseName)
1143 char *stubModuleName;
1146 stubModuleName = xmalloc(strlen(baseName) + 10);
1147 strcpy(stubModuleName, baseName);
1148 strcat(stubModuleName, "-mgr-stub");
1150 f = createFile(stubModuleName, ".c");
1152 xfree(stubModuleName);
1158 " * This C file has been generated by smidump "
1159 SMI_VERSION_STRING ".\n"
1160 " * It is intended to be used with the NET-SNMP library.\n"
1162 " * This C file is derived from the %s module.\n"
1164 " */\n\n", smiModule->name );
1167 "#include <stdlib.h>\n"
1169 "#include <ucd-snmp/asn1.h>\n"
1170 "#include <ucd-snmp/snmp.h>\n"
1171 "#include <ucd-snmp/snmp_api.h>\n"
1172 "#include <ucd-snmp/snmp_client.h>\n"
1174 "#include \"%s.h\"\n"
1178 printMgrOidDefinitions(f, smiModule);
1180 printMgrGetMethods(f, smiModule);
1182 if (fflush(f) || ferror(f)) {
1183 perror("smidump: write error");
1188 xfree(stubModuleName);
1193 static void dumpAgtImpl(SmiModule *smiModule, char *baseName)
1195 char *stubModuleName, *cModuleName;
1198 stubModuleName = xmalloc(strlen(baseName) + 10);
1199 strcpy(stubModuleName, baseName);
1200 strcat(stubModuleName, "-agt");
1203 f = createFile(stubModuleName, ".c");
1205 xfree(stubModuleName);
1209 cModuleName = translateLower(smiModule->name);
1213 " * This C file has been generated by smidump "
1214 SMI_VERSION_STRING ".\n"
1215 " * It is intended to be used with the NET-SNMP agent library.\n"
1217 " * This C file is derived from the %s module.\n"
1219 " */\n\n", smiModule->name );
1222 "#include <stdio.h>\n"
1223 "#include <string.h>\n"
1224 "#include <malloc.h>\n"
1226 "#include \"%s.h\"\n"
1228 "#include <ucd-snmp/asn1.h>\n"
1229 "#include <ucd-snmp/snmp.h>\n"
1230 "#include <ucd-snmp/snmp_api.h>\n"
1231 "#include <ucd-snmp/snmp_impl.h>\n"
1232 "#include <ucd-snmp/snmp_vars.h>\n"
1237 "static oid %s_caps[] = {0,0};\n"
1242 "void init_%s(void)\n"
1245 /* create an entry in the sysORTable */
1247 register_sysORTable(if_mib_caps, sizeof(if_mib_caps),
1248 "IF-MIB implementation version 0.0.");
1250 /* register the various parts of the MIB */
1252 register_interfaces();
1255 /* register essential callbacks */
1257 snmp_register_callback(SNMP_CALLBACK_LIBRARY,
1258 SNMP_CALLBACK_SHUTDOWN,
1267 "void deinit_%s()\n"
1269 " unregister_sysORTable(%s_caps, sizeof(%s_caps));\n"
1272 cModuleName, cModuleName, cModuleName);
1281 cModuleName, cModuleName);
1285 if (fflush(f) || ferror(f)) {
1286 perror("smidump: write error");
1291 xfree(stubModuleName);
1296 static void dumpNetSnmp(int modc, SmiModule **modv, int flags, char *output)
1301 if (flags & SMIDUMP_FLAG_UNITE) {
1302 /* not implemented yet */
1304 for (i = 0; i < modc; i++) {
1305 baseName = output ? output : translateFileName(modv[i]->name);
1306 dumpHeader(modv[i], baseName);
1308 dumpAgtStub(modv[i], baseName);
1309 dumpAgtImpl(modv[i], baseName);
1312 dumpMgrStub(modv[i], baseName);
1314 if (! output) xfree(baseName);
1324 static SmidumpDriverOption opt[] = {
1325 { "no-mgr-stubs", OPT_FLAG, &noMgrStubs, 0,
1326 "do not generate manager stub code"},
1327 { "no-agt-stubs", OPT_FLAG, &noAgtStubs, 0,
1328 "do not generate agent stub code"},
1329 { 0, OPT_END, 0, 0 }
1332 static SmidumpDriver driver = {
1336 SMIDUMP_DRIVER_CANT_UNITE,
1337 "ANSI C code for the NET-SNMP package",
1342 smidumpRegisterDriver(&driver);