📄 smux.c
字号:
&oid_name_len)) == NULL) { DEBUGMSGTL(("smux", "[smux_open_process] oid parse failed\n")); *fail = TRUE; return ((ptr += *len)); } snprint_objid(oid_print, sizeof(oid_print), oid_name, oid_name_len); if (snmp_get_do_debugging()) { DEBUGMSGTL(("smux", "[smux_open_process] smux peer: %s\n", oid_print)); DEBUGMSGTL(("smux", "[smux_open_process] len %d, type %d\n", *len, (int) type)); } string_len = SMUXMAXSTRLEN; if ((ptr = asn_parse_string(ptr, len, &type, (u_char *) descr, &string_len)) == NULL) { DEBUGMSGTL(("smux", "[smux_open_process] descr parse failed\n")); *fail = TRUE; return ((ptr += *len)); } if (snmp_get_do_debugging()) { DEBUGMSGTL(("smux", "[smux_open_process] smux peer descr: ")); for (i = 0; i < (int) string_len; i++) DEBUGMSG(("smux", "%c", descr[i])); DEBUGMSG(("smux", "\n")); DEBUGMSGTL(("smux", "[smux_open_process] len %d, type %d\n", *len, (int) type)); } descr[string_len] = 0; string_len = SMUXMAXSTRLEN; if ((ptr = asn_parse_string(ptr, len, &type, (u_char *) passwd, &string_len)) == NULL) { DEBUGMSGTL(("smux", "[smux_open_process] passwd parse failed\n")); *fail = TRUE; return ((ptr += *len)); } if (snmp_get_do_debugging()) { DEBUGMSGTL(("smux", "[smux_open_process] smux peer passwd: ")); for (i = 0; i < (int) string_len; i++) DEBUGMSG(("smux", "%c", passwd[i])); DEBUGMSG(("smux", "\n")); DEBUGMSGTL(("smux", "[smux_open_process] len %d, type %d\n", *len, (int) type)); } passwd[string_len] = '\0'; if (!smux_auth_peer(oid_name, oid_name_len, passwd, fd)) { snmp_log(LOG_WARNING, "refused smux peer: oid %s, descr %s\n", oid_print, descr); *fail = TRUE; return ptr; } snmp_log(LOG_INFO, "accepted smux peer: oid %s, descr %s\n", oid_print, descr); *fail = FALSE; return ptr;}static voidsmux_send_close(int fd, int reason){ u_char outpacket[3], *ptr; ptr = outpacket; *(ptr++) = (u_char) SMUX_CLOSE; *(ptr++) = (u_char) 1; *ptr = (u_char) (reason & 0xFF); if (snmp_get_do_debugging()) DEBUGMSGTL(("smux", "[smux_close] sending close to fd %d, reason %d\n", fd, reason)); /* * send a response back */ if (send(fd, (char *) outpacket, 3, 0) < 0) { snmp_log_perror("[smux_snmp_close] send failed"); }}static intsmux_auth_peer(oid * name, size_t namelen, char *passwd, int fd){ int i; for (i = 0; i < nauths; i++) { if (snmp_oid_compare(Auths[i]->sa_oid, Auths[i]->sa_oid_len, name, namelen) == 0) { if (!(strcmp(Auths[i]->sa_passwd, passwd)) && (Auths[i]->sa_active_fd == -1)) { /* * matched, mark the auth */ Auths[i]->sa_active_fd = fd; return 1; } } } /* * did not match oid and passwd */ return 0;}/* * XXX - Bells and Whistles: * Need to catch signal when snmpd goes down and send close pdu to gated */static u_char *smux_close_process(int fd, u_char * ptr, size_t * len){ long down = 0; int length = *len; /* * This is the integer part of the close pdu */ while (length--) { down = (down << 8) | (long) *ptr; ptr++; } DEBUGMSGTL(("smux", "[smux_close_process] close from peer on fd %d reason %d\n", fd, down)); smux_peer_cleanup(fd); return NULL;}static u_char *smux_rreq_process(int sd, u_char * ptr, size_t * len){ long priority, rpriority; long operation; oid oid_name[MAX_OID_LEN]; size_t oid_name_len; int i, result; u_char type; smux_reg *rptr, *nrptr; oid_name_len = MAX_OID_LEN; ptr = asn_parse_objid(ptr, len, &type, oid_name, &oid_name_len); DEBUGMSGTL(("smux", "[smux_rreq_process] smux subtree: ")); DEBUGMSGOID(("smux", oid_name, oid_name_len)); DEBUGMSG(("smux", "\n")); if ((ptr = asn_parse_int(ptr, len, &type, &priority, sizeof(priority))) == NULL) { DEBUGMSGTL(("smux", "[smux_rreq_process] priority parse failed\n")); smux_send_rrsp(sd, -1); return NULL; } DEBUGMSGTL(("smux", "[smux_rreq_process] priority %d\n", priority)); if ((ptr = asn_parse_int(ptr, len, &type, &operation, sizeof(operation))) == NULL) { DEBUGMSGTL(("smux", "[smux_rreq_process] operation parse failed\n")); smux_send_rrsp(sd, -1); return NULL; } DEBUGMSGTL(("smux", "[smux_rreq_process] operation %d\n", operation)); if (operation == SMUX_REGOP_DELETE) { /* * search the active list for this registration */ rptr = smux_find_match(ActiveRegs, sd, oid_name, oid_name_len, priority); if (rptr) { rpriority = rptr->sr_priority; /* * unregister the mib */ unregister_mib(rptr->sr_name, rptr->sr_name_len); /* * find a replacement */ nrptr = smux_find_replacement(rptr->sr_name, rptr->sr_name_len); if (nrptr) { /* * found one */ smux_replace_active(rptr, nrptr); } else { /* * no replacement found */ smux_list_detach(&ActiveRegs, &rptr); free(rptr); } smux_send_rrsp(sd, rpriority); return ptr; } /* * search the passive list for this registration */ rptr = smux_find_match(PassiveRegs, sd, oid_name, oid_name_len, priority); if (rptr) { rpriority = rptr->sr_priority; smux_list_detach(&PassiveRegs, &rptr); free(rptr); smux_send_rrsp(sd, rpriority); return ptr; } /* * This peer cannot unregister the tree, it does not * * belong to him. Send him an error. */ smux_send_rrsp(sd, -1); return ptr; } else if ((operation == SMUX_REGOP_REGISTER_RO) || (operation == SMUX_REGOP_REGISTER_RW)) { if (priority < -1) { DEBUGMSGTL(("smux", "[smux_rreq_process] peer fd %d invalid priority", sd, priority)); smux_send_rrsp(sd, -1); return NULL; } if ((nrptr = malloc(sizeof(smux_reg))) == NULL) { snmp_log_perror("[smux_rreq_process] malloc"); smux_send_rrsp(sd, -1); return NULL; } nrptr->sr_priority = priority; nrptr->sr_name_len = oid_name_len; nrptr->sr_fd = sd; for (i = 0; i < (int) oid_name_len; i++) nrptr->sr_name[i] = oid_name[i]; /* * See if this tree matches or scopes any of the * * active trees. */ for (rptr = ActiveRegs; rptr; rptr = rptr->sr_next) { result = snmp_oid_compare(oid_name, oid_name_len, rptr->sr_name, rptr->sr_name_len); if (result == 0) { if ((oid_name_len == rptr->sr_name_len)) { if ((nrptr->sr_priority == -1)) { nrptr->sr_priority = rptr->sr_priority; do { nrptr->sr_priority++; } while (smux_list_add(&PassiveRegs, nrptr)); goto done; } else if (nrptr->sr_priority < rptr->sr_priority) { /* * Better priority. There are no better * * priorities for this tree in the passive list, * * so replace the current active tree. */ smux_replace_active(rptr, nrptr); goto done; } else { /* * Equal or worse priority */ do { nrptr->sr_priority++; } while (smux_list_add(&PassiveRegs, nrptr) == -1); goto done; } } else if (oid_name_len < rptr->sr_name_len) { /* * This tree scopes a current active * * tree. Replace the current active tree. */ smux_replace_active(rptr, nrptr); goto done; } else { /* oid_name_len > rptr->sr_name_len */ /* * This tree is scoped by a current * * active tree. */ do { nrptr->sr_priority++; } while (smux_list_add(&PassiveRegs, nrptr) == -1); goto done; } } } /* * We didn't find it in the active list. Add it at * * the requested priority. */ if (nrptr->sr_priority == -1) nrptr->sr_priority = 0; smux_list_add(&ActiveRegs, nrptr); register_mib("smux", (struct variable *) smux_variables, sizeof(struct variable2), 1, nrptr->sr_name, nrptr->sr_name_len); done: smux_send_rrsp(sd, nrptr->sr_priority); return ptr; } else { DEBUGMSGTL(("smux", "[smux_rreq_process] unknown operation\n")); smux_send_rrsp(sd, -1); return NULL; }}/* * Find the registration with a matching descriptor, OID and priority. If * the priority is -1 then find a registration with a matching descriptor, * a matching OID, and the highest priority. */static smux_reg *smux_find_match(smux_reg * regs, int sd, oid * oid_name, size_t oid_name_len, long priority){ smux_reg *rptr, *bestrptr; bestrptr = NULL; for (rptr = regs; rptr; rptr = rptr->sr_next) { if (rptr->sr_fd != sd) continue; if (snmp_oid_compare (rptr->sr_name, rptr->sr_name_len, oid_name, oid_name_len)) continue; if (rptr->sr_priority == priority) return rptr; if (priority != -1) continue; if (bestrptr) { if (bestrptr->sr_priority > rptr->sr_priority) bestrptr = rptr; } else { bestrptr = rptr; } } return bestrptr;}static voidsmux_replace_active(smux_reg * actptr, smux_reg * pasptr){ smux_list_detach(&ActiveRegs, &actptr); unregister_mib(actptr->sr_name, actptr->sr_name_len); smux_list_detach(&PassiveRegs, &pasptr); (void) smux_list_add(&ActiveRegs, pasptr); register_mib("smux", (struct variable *) smux_variables, sizeof(struct variable2), 1, pasptr->sr_name, pasptr->sr_name_len); free(actptr);}static voidsmux_list_detach(smux_reg ** head, smux_reg ** m_remove){ smux_reg *rptr, *rptr2; if (*head == NULL) { DEBUGMSGTL(("smux", "[smux_list_detach] Ouch!")); return; } if (*head == *m_remove) { *m_remove = *head; *head = (*head)->sr_next; return; } for (rptr = *head, rptr2 = rptr->sr_next; rptr2; rptr2 = rptr2->sr_next, rptr = rptr->sr_next) { if (rptr2 == *m_remove) { *m_remove = rptr2; rptr->sr_next = rptr2->sr_next; return; } }}/* * Attempt to add a registration (in order) to a list. If the * add fails (because of an existing registration with equal * priority) return -1. */static intsmux_list_add(smux_reg ** head, smux_reg * add){ smux_reg *rptr, *prev; int result; if (*head == NULL) { *head = add; (*head)->sr_next = NULL; return 0; } prev = NULL; for (rptr = *head; rptr->sr_next; rptr = rptr->sr_next) { result = snmp_oid_compare(add->sr_name, add->sr_name_len, rptr->sr_name, rptr->sr_name_len); if ((result == 0) && (add->sr_priority == rptr->sr_priority)) { /* * same tree, same pri, nope */ return -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -