⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smux.c

📁 非常不错的网管开发包
💻 C
📖 第 1 页 / 共 3 页
字号:
		DEBUGMSGTL (("smux","[smux_pdu_process] type is %d\n", (int) type));		switch (type) {		case SMUX_OPEN:			smux_send_close(fd, SMUXC_PROTOCOLERROR);			DEBUGMSGTL (("smux","[smux_pdu_process] peer on fd %d sent duplicate open?\n", fd));			smux_peer_cleanup(fd);			error = -1;			break;		case SMUX_CLOSE:			ptr = smux_close_process(fd, ptr, &len);			smux_peer_cleanup(fd);			error = -1;			break;		case SMUX_RREQ:			ptr = smux_rreq_process(fd, ptr, &len);			break;		case SMUX_RRSP:			error = -1;			smux_send_close(fd, SMUXC_PROTOCOLERROR);			smux_peer_cleanup(fd);			DEBUGMSGTL (("smux","[smux_pdu_process] peer on fd %d sent RRSP!\n", fd));			break;		case SMUX_SOUT:			error = -1;			smux_send_close(fd, SMUXC_PROTOCOLERROR);			smux_peer_cleanup(fd);			DEBUGMSGTL (("smux","This shouldn't have happened!\n"));			break;		case SMUX_TRAP:			snmp_log(LOG_INFO, "Got trap from peer on fd %d\n", fd);			ptr = smux_trap_process(ptr, &len);			// watch out for close on top of this...should return correct end			// debug this...			ptr = NULL;			break;		default:			smux_send_close(fd, SMUXC_PACKETFORMAT);			smux_peer_cleanup(fd);			DEBUGMSGTL (("smux","[smux_pdu_process] Wrong type %d\n", (int)type));			error = -1;			break;		}	}	return error;}static u_char *smux_open_process(int fd, u_char *ptr, size_t *len, int *fail){	u_char type;	long version;	oid oid_name[MAX_OID_LEN];	char string[SMUXMAXSTRLEN];	int i;	size_t oid_name_len, string_len;	if ((ptr = asn_parse_int(ptr, len, &type, &version, 	    sizeof(version))) == NULL) {		DEBUGMSGTL (("smux","[smux_open_process] version parse failed\n"));		*fail = TRUE;		return((ptr += *len));	}	DEBUGMSGTL(("smux",                    "[smux_open_process] version %d, len %d, type %d\n",                     version, *len, (int)type));	oid_name_len = MAX_OID_LEN;	if ((ptr = asn_parse_objid(ptr, len, &type, oid_name,	    &oid_name_len)) == NULL) {		DEBUGMSGTL (("smux","[smux_open_process] oid parse failed\n"));		*fail = TRUE;		return((ptr += *len));	}        if (snmp_get_do_debugging()) {          DEBUGMSGTL (("smux","[smux_open_process] smux peer:"));           for (i=0; i < (int)oid_name_len; i++)             DEBUGMSG (("smux",".%d", oid_name[i]));          DEBUGMSG (("smux"," \n"));          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 *)string,	    &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", string[i]));          DEBUGMSG (("smux"," \n"));          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 *)string,	    &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", string[i]));          DEBUGMSG (("smux"," \n"));          DEBUGMSGTL (("smux","[smux_open_process] len %d, type %d\n", *len, (int)type));        }	string[string_len] = '\0';	if(!smux_auth_peer(oid_name, oid_name_len, string, fd)) {		if(snmp_get_do_debugging()) {		    DEBUGMSGTL (("smux","[smux_open_process] peer authentication failed for oid\n"));		    for (i = 0; i < (int)oid_name_len; i++) 			DEBUGMSG (("smux","\t.%d", oid_name[i]));		    DEBUGMSG (("smux"," password %s\n", string));		}		*fail = TRUE;		return ptr;	}	*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;			}			else				return 0;		}	}	/* 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;	int result;	if(*head == NULL) {		*head = add;		(*head)->sr_next = NULL;		return 0;	}	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;		} else if (result < 0) {			/* this can only happen if we go before the head */			add->sr_next = *head;			*head = add;			return 0;		} else if ((snmp_oid_compare(add->sr_name, add->sr_name_len,		    rptr->sr_next->sr_name, rptr->sr_next->sr_name_len)) < 0) {			/* insert here */			add->sr_next = rptr->sr_next;			rptr->sr_next = add;			return 0;		}	}	/* compare the last one */	if ((snmp_oid_compare(add->sr_name, add->sr_name_len, rptr->sr_name,	    rptr->sr_name_len) == 0) && add->sr_priority == rptr->sr_priority)		return -1;	else {		rptr->sr_next = add;		add->sr_next = NULL;	}	return 0;}/* * Find a replacement for this registration.  In order * of preference: * * 	- Least difference in subtree length *	- Best (lowest) priority * * For example, if we need to replace .1.3.6.1.69,  * we would pick .1.3.6.1.69.1 instead of .1.3.6.69.1.1 * */static smux_reg *smux_find_replacement(oid *name, size_t name_len){	smux_reg *rptr, *bestptr;	int bestlen, difflen;	bestlen = SMUX_MAX_PRIORITY;	bestptr = NULL;	for (rptr = PassiveRegs; rptr; rptr = rptr->sr_next) {		if (!compare_tree(rptr->sr_name, rptr->sr_name_len,		    name, name_len)) {			if ((difflen = rptr->sr_name_len - name_len)			    < bestlen) {				bestlen = difflen;				bestptr = rptr;			} else if ((difflen == bestlen) &&			    (rptr->sr_priority < bestptr->sr_priority)) 				bestptr = rptr;		}	}	return bestptr;}u_char *smux_snmp_process(int exact,	oid *objid,	size_t *len,	size_t *return_len,	u_char *return_type,	int sd){	u_char packet[SMUXMAXPKTSIZE], *ptr, result[SMUXMAXPKTSIZE];	size_t length = SMUXMAXPKTSIZE;	u_char type;		/* 	 * Send the query to the peer	 */	smux_reqid++;	if (exact)		type = SMUX_GET;	else		type = SMUX_GETNEXT;	if (smux_build(type, smux_reqid, objid, len, 0, NULL, 	    *len, packet, &length) < 0) {	 snmp_log(LOG_NOTICE, "[smux_snmp_process]: smux_build failed\n");		return NULL;	}    DEBUGMSGTL(("smux", "[smux_snmp_process] oid from build: "));    DEBUGMSGOID(("smux", objid, *len));    DEBUGMSG(("smux","\n"));	if (send(sd, (char *)packet, length, 0) < 0) {		snmp_log_perror("[smux_snmp_process] send failed");	}	DEBUGMSGTL(("smux",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -