$NetBSD: patch-012,v 1.1.1.1 1999/09/22 21:11:39 kim Exp $

Index: agent/snmpd.c
===================================================================
RCS file: /opt/ucd-snmp/ucd-snmp/agent/snmpd.c,v
retrieving revision 1.137
diff -c -r1.137 snmpd.c
*** snmpd.c	1999/08/23 20:54:32	1.137
--- snmpd.c	1999/08/27 02:43:49
***************
*** 202,213 ****
  
  #define NUM_SOCKETS	32
  
! #ifdef USING_SD_HANDLERS
! static int	  sdlist[NUM_SOCKETS],
! 		  sdlen = 0;
! static int	  portlist[NUM_SOCKETS];
! int		(*sd_handlers[NUM_SOCKETS]) (int);
! #endif
  
  /*
   * Prototypes.
--- 202,211 ----
  
  #define NUM_SOCKETS	32
  
! #ifdef USING_SMUX_MODULE
! static int sdlist[NUM_SOCKETS], sdlen = 0;
! int listen_sd;
! #endif /* USING_SMUX_MODULE */
  
  /*
   * Prototypes.
***************
*** 909,914 ****
--- 907,915 ----
  	struct timeval	sched,   *svp = &sched,
  	now,     *nvp = &now;
  	int count, block;
+ #ifdef	USING_SMUX_MODULE
+ 	int i, j, sd;
+ #endif	/* USING_SMUX_MODULE */
  
  
  
***************
*** 944,949 ****
--- 945,960 ----
  		snmp_select_info(&numfds, &fdset, tvp, &block);
  		if (block == 1)
  			tvp = NULL; /* block without timeout */
+ #ifdef	USING_SMUX_MODULE
+ 		if (listen_sd >= 0) {
+ 			FD_SET(listen_sd, &fdset);
+ 			numfds = listen_sd >= numfds ? listen_sd + 1 : numfds;
+ 			for (i = 0; i < sdlen; i++) {
+ 				FD_SET(sdlist[i], &fdset);
+ 				numfds = sdlist[i] >= numfds ? sdlist[i] + 1 : numfds;
+ 			}
+ 		}
+ #endif	/* USING_SMUX_MODULE */
  		count = select(numfds, &fdset, 0, 0, tvp);
  
  		if (count > 0){
***************
*** 964,969 ****
--- 975,1001 ----
  				return -1;
  		}  /* endif -- count>0 */
  
+ #ifdef	USING_SMUX_MODULE
+ 		/* handle the SMUX sd's */
+ 		if (listen_sd >= 0) {
+ 			for (i = 0; i < sdlen; i++) {
+ 				if (FD_ISSET(sdlist[i], &fdset)) {
+ 					if (smux_process(sdlist[i]) < 0) {
+ 						for (; i < (sdlen - 1); i++) {
+ 							sdlist[i] = sdlist[i+1];
+ 						}
+ 						sdlen--;
+ 					}
+ 				}
+ 			}
+ 			/* new connection */
+ 			if (FD_ISSET(listen_sd, &fdset)) {
+ 				if ((sd = smux_accept(listen_sd)) >= 0) {
+ 					sdlist[sdlen++] = sd;
+ 				}
+ 			}
+ 		}
+ #endif	/* USING_SMUX_MODULE */
  
  		/*
  		 * If the time 'now' is greater than the 'sched'uled time, then:
Index: agent/mibgroup/smux/smux.c
===================================================================
RCS file: /opt/ucd-snmp/ucd-snmp/agent/mibgroup/smux/smux.c,v
retrieving revision 1.29
diff -c -r1.29 smux.c
*** smux.c	1999/08/24 22:14:18	1.29
--- smux.c	1999/08/27 02:43:50
***************
*** 69,84 ****
  oid smux_objid[MAX_OID_LEN];
  u_char smux_str[SMUXMAXSTRLEN];
  
! #ifdef USING_SD_HANDLERS
! extern int sdlist[];
! extern int sdlen;
! extern int (*sd_handlers[])(int);
! #endif
  
  static struct timeval smux_rcv_timeout;
  static u_long smux_reqid;
  
! int 		init_smux (void);
  static u_char	*smux_open_process (int, u_char *, size_t *, int *);
  static u_char	*smux_rreq_process (int, u_char *, size_t *);
  static u_char	*smux_close_process (int, u_char *, size_t *);
--- 69,80 ----
  oid smux_objid[MAX_OID_LEN];
  u_char smux_str[SMUXMAXSTRLEN];
  
! extern int listen_sd;
  
  static struct timeval smux_rcv_timeout;
  static u_long smux_reqid;
  
! void 		init_smux (void);
  static u_char	*smux_open_process (int, u_char *, size_t *, int *);
  static u_char	*smux_rreq_process (int, u_char *, size_t *);
  static u_char	*smux_close_process (int, u_char *, size_t *);
***************
*** 161,180 ****
  	}
  }
  
! int 
  init_smux(void)
  {
  
  	struct sockaddr_in lo_socket;
- 	int smux_sd;
  	int one = 1;
  
          snmpd_register_config_handler("smuxpeer", smux_parse_peer_auth,
                                        smux_free_peer_auth,
                                        "OID-IDENTITY PASSWORD");
- 
  	/* Reqid */
  	smux_reqid = 0;
  
  	/* Receive timeout */
  	smux_rcv_timeout.tv_sec = 0;
--- 157,175 ----
  	}
  }
  
! void
  init_smux(void)
  {
  
  	struct sockaddr_in lo_socket;
  	int one = 1;
  
          snmpd_register_config_handler("smuxpeer", smux_parse_peer_auth,
                                        smux_free_peer_auth,
                                        "OID-IDENTITY PASSWORD");
  	/* Reqid */
  	smux_reqid = 0;
+ 	listen_sd = -1;
  
  	/* Receive timeout */
  	smux_rcv_timeout.tv_sec = 0;
***************
*** 185,222 ****
  	lo_socket.sin_family = AF_INET;
  	lo_socket.sin_port = htons((u_short) SMUXPORT);
  
! 	if ((smux_sd = socket (AF_INET, SOCK_STREAM, 0)) <  0) {
  		snmp_log_perror("[init_smux] socket failed");
! 		return SMUXNOTOK;
  	}
! 	if (bind (smux_sd, (struct sockaddr *) &lo_socket, 
  	    sizeof (lo_socket)) < 0) {
  		snmp_log_perror("[init_smux] bind failed");
! 		close(smux_sd);
! 		return SMUXNOTOK;
  	}
  
! 	if (setsockopt (smux_sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, 
  			sizeof (one)) < 0) {
  		snmp_log_perror("[init_smux] setsockopt(SO_KEEPALIVE) failed");
! 		close(smux_sd);
! 		return SMUXNOTOK;
  	}
! 	if(listen(smux_sd, SOMAXCONN) == -1) {
  		snmp_log_perror("[init_smux] listen failed");
! 		close(smux_sd);
! 		return SMUXNOTOK;
  	}
- #ifdef USING_SD_HANDLERS
- 	sdlist[sdlen] = smux_sd;
- 	sd_handlers[sdlen++] = smux_accept;
- 
- 	DEBUGMSGTL(("smux_init","sdlen in smux_init: %d\n", sdlen));
- #endif
- 	DEBUGMSGTL(("smux_init", "[smux_init] done; smux_sd is %d, smux_port is %d\n", smux_sd,
- 		 ntohs(lo_socket.sin_port)));
  
! 	return SMUXOK;
  }
  
  u_char *
--- 180,216 ----
  	lo_socket.sin_family = AF_INET;
  	lo_socket.sin_port = htons((u_short) SMUXPORT);
  
! 	if ((listen_sd = socket (AF_INET, SOCK_STREAM, 0)) <  0) {
  		snmp_log_perror("[init_smux] socket failed");
! 		return;
  	}
! 
! 	if (bind (listen_sd, (struct sockaddr *) &lo_socket, 
  	    sizeof (lo_socket)) < 0) {
  		snmp_log_perror("[init_smux] bind failed");
! 		close(listen_sd);
! 		listen_sd = -1;
! 		return;
  	}
  
! #ifdef	SO_KEEPALIVE
! 	if (setsockopt (listen_sd, SOL_SOCKET, SO_KEEPALIVE, (char *)&one, 
  			sizeof (one)) < 0) {
  		snmp_log_perror("[init_smux] setsockopt(SO_KEEPALIVE) failed");
! 		close(listen_sd);
! 		listen_sd = -1;
! 		return;
  	}
! #endif 	/* SO_KEEPALIVE */
! 
! 	if(listen(listen_sd, SOMAXCONN) == -1) {
  		snmp_log_perror("[init_smux] listen failed");
! 		close(listen_sd);
! 		listen_sd = -1;
! 		return;
  	}
  
! 	DEBUGMSGTL(("smux_init", "[smux_init] done; smux listen sd is %d, smux port is %d\n", listen_sd, ntohs(lo_socket.sin_port)));
  }
  
  u_char *
***************
*** 240,246 ****
  	}
  	if (rptr == NULL)
  		return NULL;
! 	else if (exact && (*length <= rptr->sr_name_len))
  		return NULL;
  
  	*write_method = var_smux_write; 
--- 234,240 ----
  	}
  	if (rptr == NULL)
  		return NULL;
! 	else if (exact && (*length < rptr->sr_name_len))
  		return NULL;
  
  	*write_method = var_smux_write; 
***************
*** 355,373 ****
  	errno = 0;
  	if((fd = accept(sd, (struct sockaddr *)&in_socket, &alen)) < 0) {
  		snmp_log_perror("[smux_accept] accept failed");
! 		return SMUXNOTOK;
  	} else {
  	 snmp_log(LOG_ERR, "[smux_accept] accepted fd %d - errno %d\n", fd, errno);
  		if (npeers + 1 == SMUXMAXPEERS) {
  			DEBUGMSGTL (("smux","[smux_accept] denied peer on fd %d, limit reached", fd));
  			close(sd);
! 			return SMUXNOTOK;
  		}
  		/* now block for an OpenPDU */
  		if ((len = recv(fd, (char *)data, SMUXMAXPKTSIZE, 0)) <= 0) {
  			DEBUGMSGTL (("smux","[smux_accept] peer on fd %d died or timed out\n", fd));
  			close(fd);
! 			return SMUXNOTOK;
  		}
  		/* try to authorize him */
  		ptr = data;
--- 349,367 ----
  	errno = 0;
  	if((fd = accept(sd, (struct sockaddr *)&in_socket, &alen)) < 0) {
  		snmp_log_perror("[smux_accept] accept failed");
! 		return -1;
  	} else {
  	 snmp_log(LOG_ERR, "[smux_accept] accepted fd %d - errno %d\n", fd, errno);
  		if (npeers + 1 == SMUXMAXPEERS) {
  			DEBUGMSGTL (("smux","[smux_accept] denied peer on fd %d, limit reached", fd));
  			close(sd);
! 			return -1;
  		}
  		/* now block for an OpenPDU */
  		if ((len = recv(fd, (char *)data, SMUXMAXPKTSIZE, 0)) <= 0) {
  			DEBUGMSGTL (("smux","[smux_accept] peer on fd %d died or timed out\n", fd));
  			close(fd);
! 			return -1;
  		}
  		/* try to authorize him */
  		ptr = data;
***************
*** 375,393 ****
  			smux_send_close(fd, SMUXC_PACKETFORMAT);
  			close(fd);
  			DEBUGMSGTL (("smux","[smux_accept] peer on %d sent bad open"));
! 			return SMUXNOTOK;
  		} else if (type != (u_char)SMUX_OPEN) {
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			close(fd);
  			DEBUGMSGTL (("smux","[smux_accept] peer on %d did not send open: (%d)\n", type));
! 			return SMUXNOTOK;
  		}
  		ptr = smux_open_process(fd, ptr, &len, &fail);
  		if (fail) {
  			smux_send_close(fd, SMUXC_AUTHENTICATIONFAILURE);
  			close(fd);
  			DEBUGMSGTL (("smux","[smux_accept] peer on %d failed authentication\n", fd));
! 			return SMUXNOTOK;
  		}
  
  		/* he's OK */
--- 369,387 ----
  			smux_send_close(fd, SMUXC_PACKETFORMAT);
  			close(fd);
  			DEBUGMSGTL (("smux","[smux_accept] peer on %d sent bad open"));
! 			return -1;
  		} else if (type != (u_char)SMUX_OPEN) {
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			close(fd);
  			DEBUGMSGTL (("smux","[smux_accept] peer on %d did not send open: (%d)\n", type));
! 			return -1;
  		}
  		ptr = smux_open_process(fd, ptr, &len, &fail);
  		if (fail) {
  			smux_send_close(fd, SMUXC_AUTHENTICATIONFAILURE);
  			close(fd);
  			DEBUGMSGTL (("smux","[smux_accept] peer on %d failed authentication\n", fd));
! 			return -1;
  		}
  
  		/* he's OK */
***************
*** 397,413 ****
                          snmp_log_perror("smux/setsockopt");
                  }
  #endif
- 
  		npeers++;
! #ifdef USING_SD_HANDLERS
! 		sdlist[sdlen] = fd;
! 		sd_handlers[sdlen++] = smux_process;
! 
! 		DEBUGMSGTL (("smux","[smux_accept] fd %d, sdlen %d\n", fd, sdlen));
! #endif
  	}
! 
! 	return SMUXOK;
  }
  
  int
--- 391,400 ----
                          snmp_log_perror("smux/setsockopt");
                  }
  #endif
  		npeers++;
! 		DEBUGMSGTL (("smux","[smux_accept] fd %d\n", fd));
  	}
! 	return fd;
  }
  
  int
***************
*** 424,435 ****
  		 */
  		DEBUGMSGTL (("smux","[smux_process] peer on fd %d died or timed out\n", fd));
  		smux_peer_cleanup(fd);
! 		return SMUXNOTOK; /* return value ignored */
  	}
  
  	DEBUGMSGTL (("smux","[smux_process] Processing %d bytes\n", length));
  
! 	error = SMUXOK;
  
  	ptr = data;
  	len = length;
--- 411,422 ----
  		 */
  		DEBUGMSGTL (("smux","[smux_process] peer on fd %d died or timed out\n", fd));
  		smux_peer_cleanup(fd);
! 		return -1;
  	}
  
  	DEBUGMSGTL (("smux","[smux_process] Processing %d bytes\n", length));
  
! 	error = 0;
  
  	ptr = data;
  	len = length;
***************
*** 442,474 ****
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			DEBUGMSGTL (("smux","[smux_process] peer on fd %d sent duplicate open?\n", fd));
  			smux_peer_cleanup(fd);
  			break;
  		case SMUX_CLOSE:
  			ptr = smux_close_process(fd, ptr, &len);
  			smux_peer_cleanup(fd);
  			break;
  		case SMUX_RREQ:
  			ptr = smux_rreq_process(fd, ptr, &len);
  			break;
  		case SMUX_RRSP:
! 			error = SMUXNOTOK;
  			ptr = NULL;
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			smux_peer_cleanup(fd);
  			DEBUGMSGTL (("smux","[smux_process] peer on fd %d sent RRSP!\n", fd));
  			break;
  		case SMUX_SOUT:
! 			error = SMUXNOTOK;
  			ptr = NULL;
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			smux_peer_cleanup(fd);
  			DEBUGMSGTL (("smux","This shouldn't have happened!\n"));
  			break;
  		default:
  			smux_send_close(fd, SMUXC_PACKETFORMAT);
  			smux_peer_cleanup(fd);
                          DEBUGMSGTL (("smux","[smux_process] Wrong type %d\n", (int)type));
! 			error = SMUXNOTOK;
  			break;
  		}
  	}
--- 429,468 ----
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			DEBUGMSGTL (("smux","[smux_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;
  			ptr = NULL;
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			smux_peer_cleanup(fd);
  			DEBUGMSGTL (("smux","[smux_process] peer on fd %d sent RRSP!\n", fd));
  			break;
  		case SMUX_SOUT:
! 			error = -1;
  			ptr = NULL;
  			smux_send_close(fd, SMUXC_PROTOCOLERROR);
  			smux_peer_cleanup(fd);
  			DEBUGMSGTL (("smux","This shouldn't have happened!\n"));
  			break;
+ 		case SMUX_TRAP:
+ 			/* just log it.. don't handle traps yet */
+ 			snmp_log(LOG_INFO, "Got trap from peer on fd %d\n", fd);
+ 			ptr += len;
+ 			break;
  		default:
  			smux_send_close(fd, SMUXC_PACKETFORMAT);
  			smux_peer_cleanup(fd);
                          DEBUGMSGTL (("smux","[smux_process] Wrong type %d\n", (int)type));
! 			error = -1;
  			break;
  		}
  	}
***************
*** 690,698 ****
  		 * belong to him.  XXX for now, ignore it.
  		 */
  		return ptr;
- 	}
  
! 	if (operation == SMUX_REGOP_REGISTER) {
  		if (priority < -1) {
  			DEBUGMSGTL (("smux","[smux_rreq_process] peer fd %d invalid priority", sd, priority));
  			return NULL;
--- 684,692 ----
  		 * belong to him.  XXX for now, ignore it.
  		 */
  		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));
  			return NULL;
***************
*** 763,775 ****
  		    smux_variables, sizeof(struct variable2),
  		    1, nrptr->sr_name, nrptr->sr_name_len);
  done:
! 		if (smux_send_rrsp(sd, nrptr->sr_priority)) 
  			DEBUGMSGTL (("smux","[smux_rreq_process]  send failed\n"));
  		return ptr;
  	}
- 
- 	DEBUGMSGTL (("smux","[smux_rreq_process] unknown operation\n"));
- 	return NULL;
  }
  
  static void
--- 757,769 ----
  		    smux_variables, sizeof(struct variable2),
  		    1, nrptr->sr_name, nrptr->sr_name_len);
  done:
! 		if (smux_send_rrsp(sd, nrptr->sr_priority) < 0) 
  			DEBUGMSGTL (("smux","[smux_rreq_process]  send failed\n"));
  		return ptr;
+ 	} else {
+ 		DEBUGMSGTL (("smux","[smux_rreq_process] unknown operation\n"));
+ 		return NULL;
  	}
  }
  
  static void
***************
*** 916,922 ****
  		type = SMUX_GETNEXT;
  
  	if (smux_build(type, smux_reqid, objid, len, 0, NULL, 
! 	    *len, packet, &length) != SMUXOK) {
  	 snmp_log(LOG_NOTICE, "[smux_snmp_process]: smux_build failed\n");
  		return NULL;
  	}
--- 910,916 ----
  		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;
  	}
***************
*** 1191,1197 ****
  
  	*length = ptr - packet;
  
! 	return SMUXOK;
  }
  
  static void
--- 1185,1191 ----
  
  	*length = ptr - packet;
  
! 	return 0;
  }
  
  static void
***************
*** 1231,1248 ****
  			free(rptr);
  		}
  	}
- #ifdef USING_SD_HANDLERS
- 	/* XXX stop paying attention to his socket */
- 	for (i = 0; i < sdlen; i++) {
- 		if (sdlist[i] == sd) {
- 			for (; i < (sdlen-1); i++) {
- 				sdlist[i] = sdlist[i+1];
- 				sd_handlers[i] = sd_handlers[i+1];
- 			}
- 		}
- 	}
- 	sdlen--;
- #endif
  
  	/* decrement the peer count */
  	npeers--;
--- 1225,1230 ----
***************
*** 1271,1279 ****
  	for(i = 0; i < 4; i++, mask >>= 8)
  		*(++ptr) = (u_char)(pri & mask);
  
! 	if((send(sd, (char *)outdata, 6, 0)) < 0)
! 		return SMUXNOTOK;
! 	else
! 		return SMUXOK;
  }
- 
--- 1253,1257 ----
  	for(i = 0; i < 4; i++, mask >>= 8)
  		*(++ptr) = (u_char)(pri & mask);
  
! 	return (send(sd, (char *)outdata, 6, 0));
  }
Index: agent/mibgroup/smux/smux.h
===================================================================
RCS file: /opt/ucd-snmp/ucd-snmp/agent/mibgroup/smux/smux.h,v
retrieving revision 1.6
diff -c -r1.6 smux.h
*** smux.h	1999/05/03 22:38:37	1.6
--- smux.h	1999/08/27 02:43:50
***************
*** 3,14 ****
   * Rewritten by Nick Amato <naamato@merit.net>.
   */
  
- #define NOTINIT  0
- #define INIT     1
- 
- #define SMUXOK      0
- #define SMUXNOTOK   -1
- 
  #define SMUXPORT 199
  
  #define SMUXMAXPKTSIZE 1500
--- 3,8 ----
***************
*** 25,30 ****
--- 19,25 ----
  #define SMUX_GETNEXT    (ASN_CONTEXT | ASN_CONSTRUCTOR | 1)
  #define SMUX_GETRSP     (ASN_CONTEXT | ASN_CONSTRUCTOR | 2)
  #define SMUX_SET	(ASN_CONTEXT | ASN_CONSTRUCTOR | 3)
+ #define SMUX_TRAP	(ASN_CONTEXT | ASN_CONSTRUCTOR | 4)
  
  #define SMUXC_GOINGDOWN                    0
  #define SMUXC_UNSUPPORTEDVERSION           1
***************
*** 36,43 ****
  #define SMUX_MAX_PEERS          10
  #define SMUX_MAX_PRIORITY       2147483647
  
! #define SMUX_REGOP_DELETE       0
! #define SMUX_REGOP_REGISTER     1
  
  /* 
   * Authorized peers read from the config file
--- 31,39 ----
  #define SMUX_MAX_PEERS          10
  #define SMUX_MAX_PRIORITY       2147483647
  
! #define SMUX_REGOP_DELETE		0
! #define SMUX_REGOP_REGISTER_RO		1
! #define SMUX_REGOP_REGISTER_RW		2
  
  /* 
   * Authorized peers read from the config file
***************
*** 60,66 ****
  	struct _smux_reg *sr_next;      /* next one                     */
  } smux_reg;
  
! extern int init_smux (void);
  extern int smux_accept (int);
  extern u_char *smux_snmp_process (int, oid *, size_t *, size_t *, u_char *, int);
  extern int smux_process (int);
--- 56,62 ----
  	struct _smux_reg *sr_next;      /* next one                     */
  } smux_reg;
  
! extern void init_smux (void);
  extern int smux_accept (int);
  extern u_char *smux_snmp_process (int, oid *, size_t *, size_t *, u_char *, int);
  extern int smux_process (int);
