index a0f150fbf281b8809eff8adc5f060ce80531a27c..bdd348f20dc50c54a3e0872ba0d1e6cfdf21c6b2 100644 (file)
-/******************************************************************************
-*
+/*****************************************************************************
+*
* Nagios check_dhcp plugin
-*
+*
* License: GPL
* Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)
-* Copyright (c) 2001-2006 Nagios Plugin Development Team
-*
-* Last Modified: $Date$
-*
+* Copyright (c) 2001-2007 Nagios Plugin Development Team
+*
* Description:
-*
+*
* This file contains the check_dhcp plugin
-*
-* This plugin tests the availability of DHCP servers on a network.
-*
-*
-* License Information:
-*
-* This program is free software; you can redistribute it and/or modify
+*
+* This plugin tests the availability of DHCP servers on a network.
+*
+* Unicast mode was originally implemented by Heiti of Boras Kommun with
+* general improvements as well as usability fixes and "forward"-porting by
+* Andreas Ericsson of OP5 AB.
+*
+*
+* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation; either version 2 of the License, or
+* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
-*
+*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
-*
+*
* You should have received a copy of the GNU General Public License
-* along with this program; if not, write to the Free Software
-* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*
-* $Id$
-*
-* ------------------------------------------------------------------------
-* Unicast mode was originally implemented by Heiti of Boras Kommun with
-* general improvements as well as usability fixes and "forward"-porting by
-* Andreas Ericsson of OP5 AB.
-* ------------------------------------------------------------------------
-*
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*
*****************************************************************************/
const char *progname = "check_dhcp";
-const char *revision = "$Revision$";
-const char *copyright = "2001-2006";
+const char *copyright = "2001-2007";
const char *email = "nagiosplug-devel@lists.sourceforge.net";
#include "common.h"
#elif defined(__sun__) || defined(__solaris__) || defined(__hpux__)
-#define INSAP 22
-#define OUTSAP 24
+#define INSAP 22
+#define OUTSAP 24
#include <signal.h>
#include <ctype.h>
#define bcopy(source, destination, length) memcpy(destination, source, length)
-#define AREA_SZ 5000 /* buffer length in bytes */
+#define AREA_SZ 5000 /* buffer length in bytes */
static u_long ctl_area[AREA_SZ];
static u_long dat_area[AREA_SZ];
static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area};
static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area};
-#define GOT_CTRL 1
-#define GOT_DATA 2
-#define GOT_BOTH 3
-#define GOT_INTR 4
-#define GOT_ERR 128
+#define GOT_CTRL 1
+#define GOT_DATA 2
+#define GOT_BOTH 3
+#define GOT_INTR 4
+#define GOT_ERR 128
#define u_int8_t uint8_t
#define u_int16_t uint16_t
#define DHCP_INFINITE_TIME 0xFFFFFFFF
#define DHCP_BROADCAST_FLAG 32768
-#define DHCP_UNICAST_FLAG 0
#define DHCP_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68
requested_server *requested_server_list=NULL;
int valid_responses=0; /* number of valid DHCPOFFERs we received */
-int requested_servers=0;
+int requested_servers=0;
int requested_responses=0;
int request_specific_address=FALSE;
void print_usage(void);
void print_help(void);
+void resolve_host(const char *in,struct in_addr *out);
unsigned char *mac_aton(const char *);
void print_hardware_address(const unsigned char *);
int get_hardware_address(int,char *);
int dhcp_socket;
int result = STATE_UNKNOWN;
- /* this plugin almost certainly needs root permissions. */
- np_warn_if_not_root();
-
setlocale (LC_ALL, "");
bindtextdomain (PACKAGE, LOCALEDIR);
textdomain (PACKAGE);
+ /* Parse extra opts if any */
+ argv=np_extra_opts(&argc, argv, progname);
+
if(process_arguments(argc,argv)!=OK){
usage4 (_("Could not parse arguments"));
}
+ /* this plugin almost certainly needs root permissions. */
+ np_warn_if_not_root();
+
/* create socket for DHCP communications */
dhcp_socket=create_dhcp_socket();
strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)-1);
ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0';
-
+
/* try and grab hardware address of requested interface */
if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){
printf(_("Error: Could not get hardware address of interface '%s'\n"),interface_name);
unit = atoi(p) ;
*p = '\0' ;
strncat(dev, interface_name, 6) ;
- }
+ }
else{
printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name);
exit(STATE_UNKNOWN);
opts += sizeof(requested_address);
}
discover_packet.options[opts++]=DHCP_OPTION_END;
-
+
/* unicast fields */
if(unicast)
discover_packet.giaddr.s_addr = my_ip.s_addr;
/* send the DHCPDISCOVER packet out */
send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast);
- if(verbose)
+ if(verbose)
printf("\n\n");
return OK;
if((current_time-start_time)>=dhcpoffer_timeout)
break;
- if(verbose)
+ if(verbose)
printf("\n\n");
bzero(&source,sizeof(source));
result=OK;
result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source);
-
+
if(result!=OK){
if(verbose)
printf(_("Result=ERROR\n"));
continue;
}
else{
- if(verbose)
+ if(verbose)
printf(_("Result=OK\n"));
responses++;
printf("\n");
if(result==ERROR){
- if(verbose)
+ if(verbose)
printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n"));
continue;
@@ -662,7 +656,7 @@ int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in
result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)dest,sizeof(*dest));
- if(verbose)
+ if(verbose)
printf(_("send_dhcp_packet result: %d\n"),result);
if(result<0)
}
/* set the broadcast option - we need this to listen to DHCP broadcast messages */
- if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){
+ if(!unicast && setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){
printf(_("Error: Could not set broadcast option on DHCP socket!\n"));
exit(STATE_UNKNOWN);
}
/* get option length */
option_length=offer_packet->options[x++];
- if(verbose)
+ if(verbose)
printf("Option: %d (0x%02X)\n",option_type,option_length);
/* get option data */
next_server=this_server->next;
free(this_server);
}
-
+
return OK;
}
/* get max lease time we were offered */
if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME)
max_lease_time=temp_offer->lease_time;
-
+
/* see if we got the address we requested */
if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address)))
received_requested_address=TRUE;
if(verbose){
printf(_("DHCP Server Match: Offerer=%s"),inet_ntoa(temp_offer->server_address));
printf(_(" Requested=%s"),inet_ntoa(temp_server->server_address));
- if(temp_server->answered)
+ if(temp_server->answered)
printf(_(" (duplicate)"));
printf(_("\n"));
}
/* get max lease time we were offered */
if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME)
max_lease_time=temp_offer->lease_time;
-
+
/* see if we got the address we requested */
if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address)))
received_requested_address=TRUE;
int call_getopt(int argc, char **argv){
int c=0;
int i=0;
- struct in_addr ipaddress;
int option_index = 0;
static struct option long_options[] =
- {
+ {
{"serverip", required_argument,0,'s'},
{"requestedip", required_argument,0,'r'},
{"timeout", required_argument,0,'t'},
switch(c){
case 's': /* DHCP server address */
- if(inet_aton(optarg,&ipaddress)){
- add_requested_server(ipaddress);
- inet_aton(optarg, &dhcp_ip);
- if (verbose)
- printf("querying %s\n",inet_ntoa(dhcp_ip));
- }
- /*
- else
- usage("Invalid server IP address\n");
- */
+ resolve_host(optarg,&dhcp_ip);
+ add_requested_server(dhcp_ip);
break;
case 'r': /* address we are requested from DHCP servers */
- if(inet_aton(optarg,&ipaddress)){
- requested_address=ipaddress;
- request_specific_address=TRUE;
- }
- /*
- else
- usage("Invalid requested IP address\n");
- */
+ resolve_host(optarg,&requested_address);
+ request_specific_address=TRUE;
break;
case 't': /* timeout */
break;
case 'V': /* version */
- print_revision(progname,revision);
+ print_revision(progname, NP_VERSION);
exit(STATE_OK);
case 'h': /* help */
/***********************************************************************
* interface:
- * function mac_addr_dlpi - get the mac address of the interface with
+ * function mac_addr_dlpi - get the mac address of the interface with
* type dev (eg lnc, hme) and unit (0, 1 ..)
*
* parameter: addr: an array of six bytes, has to be allocated by the caller
#endif
+/* resolve host name or die (TODO: move this to netutils.c!) */
+void resolve_host(const char *in,struct in_addr *out){
+ struct addrinfo hints, *ai;
+
+ memset(&hints,0,sizeof(hints));
+ hints.ai_family=PF_INET;
+ if (getaddrinfo(in,NULL,&hints,&ai) != 0)
+ usage_va(_("Invalid hostname/address - %s"),optarg);
+
+ memcpy(out,&((struct sockaddr_in *)ai->ai_addr)->sin_addr,sizeof(*out));
+ freeaddrinfo(ai);
+ }
+
+
/* parse MAC address string, return 6 bytes (unterminated) or NULL */
unsigned char *mac_aton(const char *string){
static unsigned char result[6];
/* print usage help */
void print_help(void){
- print_revision(progname,revision);
+ print_revision(progname, NP_VERSION);
printf("Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)\n");
printf (COPYRIGHT, copyright, email);
-
+
printf("%s\n", _("This plugin tests the availability of DHCP servers on a network."));
printf ("\n\n");
print_usage();
printf (_(UT_HELP_VRSN));
+ printf (_(UT_EXTRA_OPTS));
printf (_(UT_VERBOSE));
printf (" %s\n", "-u, --unicast");
printf (" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s"));
+#ifdef NP_EXTRA_OPTS
+ printf ("\n");
+ printf ("%s\n", _("Notes:"));
+ printf (_(UT_EXTRA_OPTS_NOTES));
+#endif
+
+ printf (_(UT_SUPPORT));
return;
}
void
print_usage(void){
-
+
printf (_("Usage:"));
printf (" %s [-v] [-u] [-s serverip] [-r requestedip] [-t timeout]\n",progname);
printf (" [-i interface] [-m mac]\n");
-
+
return;
}