📄 smux.c
字号:
u_char buf[BUFSIZ]; u_char *ptr; int len, length; struct in_addr addr; unsigned long val; u_char *h1, *h1e; ptr = buf; len = BUFSIZ; length = len; /* When SMUX connection is not established. */ if (smux_sock < 0) return 0; /* SMUX header. */ ptr = asn_build_header (ptr, &len, (u_char) SMUX_TRAP, 0); /* Sub agent enterprise oid. */ ptr = asn_build_objid (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), smux_oid, smux_oid_len); /* IP address. */ addr.s_addr = 0; ptr = asn_build_string (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_IPADDRESS), (u_char *)&addr, sizeof (struct in_addr)); /* Generic trap integer. */ val = SNMP_TRAP_ENTERPRISESPECIFIC; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &val, sizeof (int)); /* Specific trap integer. */ val = sptrap; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &val, sizeof (int)); /* Timeticks timestamp. */ val = 0; ptr = asn_build_unsigned_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_TIMETICKS), &val, sizeof (int)); /* Variables. */ h1 = ptr; ptr = asn_build_sequence (ptr, &len, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), 0); /* Iteration for each objects. */ h1e = ptr; for (i = 0; i < trapobjlen; i++) { int ret; oid oid[MAX_OID_LEN]; size_t oid_len; void *val; size_t val_len; u_char val_type; /* Make OID. */ oid_copy (oid, name, namelen); oid_copy (oid + namelen, trapobj[i].name, trapobj[i].namelen); oid_copy (oid + namelen + trapobj[i].namelen, iname, inamelen); oid_len = namelen + trapobj[i].namelen + inamelen; if (debug_smux) smux_oid_dump ("Trap", oid, oid_len); ret = smux_get (oid, &oid_len, 1, &val_type, &val, &val_len); if (debug_smux) zlog_info ("smux_get result %d", ret); if (ret == 0) ptr = snmp_build_var_op (ptr, oid, &oid_len, val_type, val_len, val, &len); } /* Now variable size is known, fill in size */ asn_build_sequence(h1, &length, (u_char) (ASN_SEQUENCE | ASN_CONSTRUCTOR), ptr - h1e); /* Fill in size of whole sequence */ len = BUFSIZ; asn_build_header (buf, &len, (u_char) SMUX_TRAP, (ptr - buf) - 2); return send (smux_sock, buf, (ptr - buf), 0);}intsmux_register (int sock){ u_char buf[BUFSIZ]; u_char *ptr; int len, ret; long priority; long operation; struct subtree *subtree; struct listnode *node; ret = 0; for (node = treelist->head; node; node = node->next) { ptr = buf; len = BUFSIZ; subtree = node->data; /* SMUX RReq Header. */ ptr = asn_build_header (ptr, &len, (u_char) SMUX_RREQ, 0); /* Register MIB tree. */ ptr = asn_build_objid (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OBJECT_ID), subtree->name, subtree->name_len); /* Priority. */ priority = -1; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &priority, sizeof (u_long)); /* Operation. */ operation = 2; /* Register R/W */ ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), &operation, sizeof (u_long)); if (debug_smux) { smux_oid_dump ("SMUX register oid", subtree->name, subtree->name_len); zlog_info ("SMUX register priority: %ld", priority); zlog_info ("SMUX register operation: %ld", operation); } len = BUFSIZ; asn_build_header (buf, &len, (u_char) SMUX_RREQ, (ptr - buf) - 2); ret = send (sock, buf, (ptr - buf), 0); if (ret < 0) return ret; } return ret;}/* Try to connect to SNMP agent. */intsmux_connect (struct thread *t){ int ret; if (debug_smux) zlog_info ("SMUX connect try %d", fail + 1); /* Clear thread poner of myself. */ smux_connect_thread = NULL; /* Make socket. Try to connect. */ smux_sock = smux_socket (); if (smux_sock < 0) { if (++fail < SMUX_MAX_FAILURE) smux_event (SMUX_CONNECT, 0); return 0; } /* Send OPEN PDU. */ ret = smux_open (smux_sock); if (ret < 0) { zlog_warn ("SMUX open message send failed: %s", strerror (errno)); close (smux_sock); smux_sock = -1; if (++fail < SMUX_MAX_FAILURE) smux_event (SMUX_CONNECT, 0); return -1; } /* Send any outstanding register PDUs. */ ret = smux_register (smux_sock); if (ret < 0) { zlog_warn ("SMUX register message send failed: %s", strerror (errno)); close (smux_sock); smux_sock = -1; if (++fail < SMUX_MAX_FAILURE) smux_event (SMUX_CONNECT, 0); return -1; } /* Everything goes fine. */ smux_event (SMUX_READ, smux_sock); return 0;}/* Clear all SMUX related resources. */voidsmux_stop (){ if (smux_read_thread) thread_cancel (smux_read_thread); if (smux_connect_thread) thread_cancel (smux_connect_thread); if (smux_sock >= 0) { close (smux_sock); smux_sock = -1; }}extern struct thread_master *master;voidsmux_event (enum smux_event event, int sock){ switch (event) { case SMUX_SCHEDULE: smux_connect_thread = thread_add_event (master, smux_connect, NULL, 0); break; case SMUX_CONNECT: smux_connect_thread = thread_add_timer (master, smux_connect, NULL, 10); break; case SMUX_READ: smux_read_thread = thread_add_read (master, smux_read, NULL, sock); break; default: break; }}intsmux_str2oid (char *str, oid *oid, size_t *oid_len){ int len; int val; len = 0; val = 0; *oid_len = 0; if (*str == '.') str++; if (*str == '\0') return 0; while (1) { if (! isdigit (*str)) return -1; while (isdigit (*str)) { val *= 10; val += (*str - '0'); str++; } if (*str == '\0') break; if (*str != '.') return -1; oid[len++] = val; val = 0; str++; } oid[len++] = val; *oid_len = len; return 0;}oid *smux_oid_dup (oid *objid, size_t objid_len){ oid *new; new = XMALLOC (MTYPE_TMP, sizeof (oid) * objid_len); oid_copy (new, objid, objid_len); return new;}intsmux_peer_oid (struct vty *vty, char *oid_str, char *passwd_str){ int ret; oid oid[MAX_OID_LEN]; size_t oid_len; ret = smux_str2oid (oid_str, oid, &oid_len); if (ret != 0) { vty_out (vty, "object ID malformed%s", VTY_NEWLINE); return CMD_WARNING; } if (smux_oid && smux_oid != smux_default_oid) free (smux_oid); if (smux_passwd && smux_passwd != smux_default_passwd) { free (smux_passwd); smux_passwd = NULL; } smux_oid = smux_oid_dup (oid, oid_len); smux_oid_len = oid_len; if (passwd_str) smux_passwd = strdup (passwd_str); return CMD_SUCCESS;}intsmux_header_generic (struct variable *v, oid *name, size_t *length, int exact, size_t *var_len, WriteMethod **write_method){ oid fulloid[MAX_OID_LEN]; int ret; oid_copy (fulloid, v->name, v->namelen); fulloid[v->namelen] = 0; /* Check against full instance. */ ret = oid_compare (name, *length, fulloid, v->namelen + 1); /* Check single instance. */ if ((exact && (ret != 0)) || (!exact && (ret >= 0))) return MATCH_FAILED; /* In case of getnext, fill in full instance. */ memcpy (name, fulloid, (v->namelen + 1) * sizeof (oid)); *length = v->namelen + 1; *write_method = 0; *var_len = sizeof(long); /* default to 'long' results */ return MATCH_SUCCEEDED;}intsmux_peer_default (){ if (smux_oid != smux_default_oid) { free (smux_oid); smux_oid = smux_default_oid; smux_oid_len = smux_default_oid_len; } if (smux_passwd != smux_default_passwd) { free (smux_passwd); smux_passwd = smux_default_passwd; } return CMD_SUCCESS;}DEFUN (smux_peer, smux_peer_cmd, "smux peer OID", "SNMP MUX protocol settings\n" "SNMP MUX peer settings\n" "Object ID used in SMUX peering\n"){ return smux_peer_oid (vty, argv[0], NULL);}DEFUN (smux_peer_password, smux_peer_password_cmd, "smux peer OID PASSWORD", "SNMP MUX protocol settings\n" "SNMP MUX peer settings\n" "SMUX peering object ID\n" "SMUX peering password\n"){ return smux_peer_oid (vty, argv[0], argv[1]);}DEFUN (no_smux_peer, no_smux_peer_cmd, "no smux peer OID", NO_STR "SNMP MUX protocol settings\n" "SNMP MUX peer settings\n" "Object ID used in SMUX peering\n"){ return smux_peer_default ();}DEFUN (no_smux_peer_password, no_smux_peer_password_cmd, "no smux peer OID PASSWORD", NO_STR "SNMP MUX protocol settings\n" "SNMP MUX peer settings\n" "SMUX peering object ID\n" "SMUX peering password\n"){ return smux_peer_default ();}intconfig_write_smux (struct vty *vty){ int first = 1; int i; if (smux_oid != smux_default_oid || smux_passwd != smux_default_passwd) { vty_out (vty, "smux peer "); for (i = 0; i < smux_oid_len; i++) { vty_out (vty, "%s%d", first ? "" : ".", (int) smux_oid[i]); first = 0; } vty_out (vty, " %s%s", smux_passwd, VTY_NEWLINE); } return 0;}/* Register subtree to smux master tree. */voidsmux_register_mib (char *descr, struct variable *var, size_t width, int num, oid name[], size_t namelen){ struct subtree *tree; tree = (struct subtree *)malloc(sizeof(struct subtree)); oid_copy (tree->name, name, namelen); tree->name_len = namelen; tree->variables = var; tree->variables_num = num; tree->variables_width = width; tree->registered = 0; listnode_add_sort(treelist, tree);}voidsmux_reset (){ /* Setting configuration to default. */ smux_peer_default ();}/* Compare function to keep treelist sorted */static intsmux_tree_cmp(struct subtree *tree1, struct subtree *tree2){ return oid_compare(tree1->name, tree1->name_len, tree2->name, tree2->name_len);}/* Initialize some values then schedule first SMUX connection. */voidsmux_init (oid defoid[], size_t defoid_len){ /* Set default SMUX oid. */ smux_default_oid = defoid; smux_default_oid_len = defoid_len; smux_oid = smux_default_oid; smux_oid_len = smux_default_oid_len; smux_passwd = smux_default_passwd; /* Make MIB tree. */ treelist = list_new(); treelist->cmp = (int (*)(void *, void *))smux_tree_cmp; /* Install commands. */ install_node (&smux_node, config_write_smux); install_element (CONFIG_NODE, &smux_peer_cmd); install_element (CONFIG_NODE, &smux_peer_password_cmd); install_element (CONFIG_NODE, &no_smux_peer_cmd); install_element (CONFIG_NODE, &no_smux_peer_password_cmd);}voidsmux_start(void){ /* Schedule first connection. */ smux_event (SMUX_SCHEDULE, 0);}#endif /* HAVE_SNMP */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -