/*
* snmpd.c
*/
/** @defgroup agent The Net-SNMP agent
* The snmp agent responds to SNMP queries from management stations
*/
/* Portions of this file are subject to the following copyrights. See
* the Net-SNMP's COPYING file for more details and other copyrights
* that may apply:
*/
/*
* Copyright 1988, 1989 by Carnegie Mellon University
*
* All Rights Reserved
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and that
* both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of CMU not be
* used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* CMU DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
* CMU BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
* WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
* *****************************************************************
*/
/*
* Copyright � 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms specified in the COPYING file
* distributed with the Net-SNMP package.
*/
#include <net-snmp/net-snmp-config.h>
#if HAVE_IO_H
#include <io.h>
#endif
#include <stdio.h>
#include <errno.h>
#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#if HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#if HAVE_ARPA_INET_H
#include <arpa/inet.h>
#endif
#if TIME_WITH_SYS_TIME
# ifdef WIN32
# include <sys/timeb.h>
# else
# include <sys/time.h>
# endif
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#if HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#elif HAVE_WINSOCK_H
#include <winsock.h>
#endif
#if HAVE_NET_IF_H
#include <net/if.h>
#endif
#if HAVE_INET_MIB2_H
#include <inet/mib2.h>
#endif
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#if HAVE_SYS_FILE_H
#include <sys/file.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#if HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
#include <signal.h>
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#if HAVE_PROCESS_H /* Win32-getpid */
#include <process.h>
#endif
#if HAVE_LIMITS_H
#include <limits.h>
#endif
#if HAVE_PWD_H
#include <pwd.h>
#endif
#if HAVE_GRP_H
#include <grp.h>
#endif
#ifndef PATH_MAX
# ifdef _POSIX_PATH_MAX
# define PATH_MAX _POSIX_PATH_MAX
# else
# define PATH_MAX 255
# endif
#endif
#ifndef FD_SET
typedef long fd_mask;
#define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) memset((p), 0, sizeof(*(p)))
#endif
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/library/fd_event_manager.h>
#include "m2m.h"
#include <net-snmp/agent/mib_module_config.h>
#include "snmpd.h"
#include "mibgroup/struct.h"
#include <net-snmp/agent/mib_modules.h>
#include "mibgroup/util_funcs.h"
#include <net-snmp/agent/agent_trap.h>
#include <net-snmp/agent/table.h>
#include <net-snmp/agent/table_iterator.h>
#include "mib_module_includes.h"
/*
* Include winservice.h to support Windows Service
*/
#ifdef WIN32
#include <windows.h>
#include <tchar.h>
#include <net-snmp/library/winservice.h>
#define WIN32SERVICE
#endif
/*
* Globals.
*/
#ifdef NETSNMP_USE_LIBWRAP
#include <tcpd.h>
#endif /* NETSNMP_USE_LIBWRAP */
#define TIMETICK 500000L
int snmp_dump_packet;
int reconfig = 0;
int Facility = LOG_DAEMON;
#ifdef WIN32SERVICE
/*
* SNMP Agent Status
*/
#define AGENT_RUNNING 1
#define AGENT_STOPPED 0
int agent_status = AGENT_STOPPED;
/* app_name_long used for Event Log (syslog), SCM, registry etc */
LPTSTR app_name_long = _T("Net-SNMP Agent"); /* Application Name */
#endif
const char *app_name = "snmpd";
extern int netsnmp_running;
extern char **argvrestartp;
extern char *argvrestart;
extern char *argvrestartname;
#ifdef USING_SMUX_MODULE
#include <mibgroup/smux/smux.h>
#endif /* USING_SMUX_MODULE */
/*
* Prototypes.
*/
int snmp_read_packet(int);
int snmp_input(int, netsnmp_session *, int, netsnmp_pdu *,
void *);
static void usage(char *);
static void SnmpTrapNodeDown(void);
static int receive(void);
#ifdef WIN32SERVICE
void StopSnmpAgent(void);
int SnmpDaemonMain(int argc, TCHAR * argv[]);
int __cdecl _tmain(int argc, TCHAR * argv[]);
#else
int main(int, char **);
#endif
/*
* These definitions handle 4.2 systems without additional syslog facilities.
*/
#ifndef LOG_CONS
#define LOG_CONS 0 /* Don't bother if not defined... */
#endif
#ifndef LOG_PID
#define LOG_PID 0 /* Don't bother if not defined... */
#endif
#ifndef LOG_LOCAL0
#define LOG_LOCAL0 0
#endif
#ifndef LOG_LOCAL1
#define LOG_LOCAL1 0
#endif
#ifndef LOG_LOCAL2
#define LOG_LOCAL2 0
#endif
#ifndef LOG_LOCAL3
#define LOG_LOCAL3 0
#endif
#ifndef LOG_LOCAL4
#define LOG_LOCAL4 0
#endif
#ifndef LOG_LOCAL5
#define LOG_LOCAL5 0
#endif
#ifndef LOG_LOCAL6
#define LOG_LOCAL6 0
#endif
#ifndef LOG_LOCAL7
#define LOG_LOCAL7 0
#endif
#ifndef LOG_DAEMON
#define LOG_DAEMON 0
#endif
static void
usage(char *prog)
{
#ifdef WIN32SERVICE
printf("\nUsage: %s [-register] [-quiet] [OPTIONS] [LISTENING ADDRESSES]",
prog);
printf("\n %s [-unregister] [-quiet]", prog);
#else
printf("\nUsage: %s [OPTIONS] [LISTENING ADDRESSES]", prog);
#endif
printf("\n");
printf("\n\tVersion: %s\n", netsnmp_get_version());
printf("\tWeb: http://www.net-snmp.org/\n");
printf("\tEmail: net-snmp-coders@lists.sourceforge.net\n");
printf("\n -a\t\t\tlog addresses\n");
printf(" -A\t\t\tappend to the logfile rather than truncating it\n");
printf(" -c FILE[,...]\t\tread FILE(s) as configuration file(s)\n");
printf(" -C\t\t\tdo not read the default configuration files\n");
printf(" -d\t\t\tdump sent and received SNMP packets\n");
printf(" -D TOKEN[,...]\tturn on debugging output for the given TOKEN(s)\n"
"\t\t\t (try ALL for extremely verbose output)\n");
printf(" -f\t\t\tdo not fork from the shell\n");
#if HAVE_UNISTD_H
printf(" -g GID\t\tchange to this numeric gid after opening\n"
"\t\t\t transport endpoints\n");
#endif
printf(" -h, --help\t\tdisplay this usage message\n");
printf(" -H\t\t\tdisplay configuration file directives understood\n");
printf(" -I [-]INITLIST\tlist of mib modules to initialize (or not)\n");
printf("\t\t\t (run snmpd with -Dmib_init for a list)\n");
printf(" -L <LOGOPTS>\t\ttoggle options controlling where to log to\n");
snmp_log_options_usage("\t", stdout);
printf(" -m MIBLIST\t\tuse MIBLIST instead of the default MIB list\n");
printf(" -M DIRLIST\t\tuse DIRLIST as the list of locations\n\t\t\t to look for MIBs\n");
printf(" -p FILE\t\tstore process id in FILE\n");
printf(" -q\t\t\tprint information in a more parsable format\n");
printf(" -r\t\t\tdo not exit if files only accessible to root\n"
"\t\t\t cannot be opened\n");
#ifdef WIN3