--- ../nplg/plugins/check_dhcp.c 2005-01-28 15:00:58.000000000 +0100 +++ ./plugins/check_dhcp.c 2005-06-08 15:28:58.000000000 +0200 @@ -22,12 +22,18 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * -* $Id: check_dhcp.c,v 1.7 2005/01/25 18:11:21 harpermann Exp $ +*-------------------------------------------------------------------------- +* 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. +*-------------------------------------------------------------------------- +* +* $Id: check_dhcp.c,v 1.9 2005/06/07 15:57:53 exon Exp $ * *****************************************************************************/ const char *progname = "check_dhcp"; -const char *revision = "$Revision: 1.7 $"; +const char *revision = "$Revision: 1.9 $"; const char *copyright = "2001-2004"; const char *email = "nagiosplug-devel@lists.sourceforge.net"; @@ -64,8 +70,8 @@ #elif defined(__sun__) || defined(__solaris__) || defined(__hpux__) -#define INSAP 22 -#define OUTSAP 24 +#define INSAP 22 +#define OUTSAP 24 #include #include @@ -73,19 +79,17 @@ #include #include -#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}; +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 @@ -97,26 +101,11 @@ static int put_both(int, int, int, int); static int dl_open(const char *, int, int *); static int dl_bind(int, int, u_char *); -long mac_addr_dlpi( const char *, int, u_char *); +static long mac_addr_dlpi(const char *, int, u_char *); #endif -#define HAVE_GETOPT_H - - -/**** Common definitions ****/ - -#define STATE_OK 0 -#define STATE_WARNING 1 -#define STATE_CRITICAL 2 -#define STATE_UNKNOWN -1 - -#define OK 0 -#define ERROR -1 - -#define FALSE 0 -#define TRUE 1 - +static int add_requested_server(struct in_addr server_address); /**** DHCP definitions ****/ @@ -126,39 +115,39 @@ #define MAX_DHCP_OPTIONS_LENGTH 312 -typedef struct dhcp_packet_struct{ - u_int8_t op; /* packet type */ - u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ - u_int8_t hlen; /* length of hardware address (of this machine) */ - u_int8_t hops; /* hops */ - u_int32_t xid; /* random transaction id number - chosen by this machine */ - u_int16_t secs; /* seconds used in timing */ - u_int16_t flags; /* flags */ - struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ - struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ - struct in_addr siaddr; /* IP address of DHCP server */ - struct in_addr giaddr; /* IP address of DHCP relay */ - unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ - char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ - char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ - char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ - }dhcp_packet; - - -typedef struct dhcp_offer_struct{ - struct in_addr server_address; /* address of DHCP server that sent this offer */ - struct in_addr offered_address; /* the IP address that was offered to us */ - u_int32_t lease_time; /* lease time in seconds */ - u_int32_t renewal_time; /* renewal time in seconds */ - u_int32_t rebinding_time; /* rebinding time in seconds */ +typedef struct dhcp_packet_struct { + u_int8_t op; /* packet type */ + u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ + u_int8_t hlen; /* length of hardware address (of this machine) */ + u_int8_t hops; /* hops */ + u_int32_t xid; /* random transaction id number - chosen by this machine */ + u_int16_t secs; /* seconds used in timing */ + u_int16_t flags; /* flags */ + struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ + struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ + struct in_addr siaddr; /* IP address of DHCP server */ + struct in_addr giaddr; /* IP address of DHCP relay */ + unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ + char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ + char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ + char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ +} dhcp_packet; + + +typedef struct dhcp_offer_struct { + struct in_addr server_address; /* address of DHCP server that sent this offer */ + struct in_addr offered_address; /* the IP address that was offered to us */ + u_int32_t lease_time; /* lease time in seconds */ + u_int32_t renewal_time; /* renewal time in seconds */ + u_int32_t rebinding_time; /* rebinding time in seconds */ struct dhcp_offer_struct *next; - }dhcp_offer; +} dhcp_offer; -typedef struct requested_server_struct{ +typedef struct requested_server_struct { struct in_addr server_address; struct requested_server_struct *next; - }requested_server; +} requested_server; #define BOOTREQUEST 1 @@ -183,35 +172,40 @@ #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 -#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ -#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ +#define ETH_HW_ADDR 1 /* used in htype field of dhcp packet */ +#define ETH_HW_ADDR_LEN 6 /* length of Ethernet hardware addresses */ -unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; +u_int8_t unicast_hops = 0; /* number of hops for unicast dhcp */ +struct in_addr my_ip; /* our address (required for relay) */ +struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ +struct sockaddr_in *my_addr; /* used to obtain our address */ +unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH] = ""; -char network_interface_name[8]="eth0"; +char network_interface_name[8] = "eth0"; -u_int32_t packet_xid=0; +u_int32_t packet_xid = 0; -u_int32_t dhcp_lease_time=0; -u_int32_t dhcp_renewal_time=0; -u_int32_t dhcp_rebinding_time=0; +u_int32_t dhcp_lease_time = 0; +u_int32_t dhcp_renewal_time = 0; +u_int32_t dhcp_rebinding_time = 0; -int dhcpoffer_timeout=2; +int dhcpoffer_timeout = 2; -dhcp_offer *dhcp_offer_list=NULL; -requested_server *requested_server_list=NULL; +dhcp_offer *dhcp_offer_list = NULL; +requested_server *requested_server_list = NULL; -int valid_responses=0; /* number of valid DHCPOFFERs we received */ -int requested_servers=0; -int requested_responses=0; +int valid_responses = 0; /* number of valid DHCPOFFERs we received */ +int requested_servers = 0; +int requested_responses = 0; -int request_specific_address=FALSE; -int received_requested_address=FALSE; -int verbose=0; +int request_specific_address = FALSE; +int received_requested_address = FALSE; +int verbose = 0; struct in_addr requested_address; @@ -221,41 +215,42 @@ void print_usage(void); void print_help(void); -int get_hardware_address(int,char *); +int get_hardware_address(int, char *); int send_dhcp_discover(int); int get_dhcp_offer(int); int get_results(void); -int add_dhcp_offer(struct in_addr,dhcp_packet *); +int add_dhcp_offer(struct in_addr, dhcp_packet *); int free_dhcp_offer_list(void); int free_requested_server_list(void); int create_dhcp_socket(void); -int close_dhcp_socket(int); -int send_dhcp_packet(void *,int,int,struct sockaddr_in *); -int receive_dhcp_packet(void *,int,int,int,struct sockaddr_in *); +int send_dhcp_packet(void *, int, int, struct sockaddr_in *); +int receive_dhcp_packet(void *, int, int, int, struct sockaddr_in *); -int main(int argc, char **argv){ +int +main(int argc, char **argv) +{ int dhcp_socket; int result; - setlocale (LC_ALL, ""); - bindtextdomain (PACKAGE, LOCALEDIR); - textdomain (PACKAGE); - - if(process_arguments(argc,argv)!=OK){ - usage4 (_("Could not parse arguments")); - } + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if(process_arguments(argc, argv) != OK) { + usage4(_("Could not parse arguments")); + } /* create socket for DHCP communications */ - dhcp_socket=create_dhcp_socket(); + dhcp_socket = create_dhcp_socket(); /* get hardware address of client machine */ - get_hardware_address(dhcp_socket,network_interface_name); + get_hardware_address(dhcp_socket, network_interface_name); /* send DHCPDISCOVER packet */ send_dhcp_discover(dhcp_socket); @@ -264,930 +259,967 @@ get_dhcp_offer(dhcp_socket); /* close socket we created */ - close_dhcp_socket(dhcp_socket); + close(dhcp_socket); /* determine state/plugin output to return */ - result=get_results(); + result = get_results(); /* free allocated memory */ free_dhcp_offer_list(); free_requested_server_list(); return result; - } - +} /* determines hardware address on client machine */ -int get_hardware_address(int sock,char *interface_name){ - +int +get_hardware_address(int sock, char *interface_name) +{ int i; #if defined(__linux__) struct ifreq ifr; - strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)); - + strncpy((char *)&ifr.ifr_name, interface_name, sizeof(ifr.ifr_name)); + /* 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); + if(ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { + printf(_("Error: Could not get hardware address of interface '%s'\n"), + interface_name); exit(STATE_UNKNOWN); - } + } + memcpy(&client_hardware_address[0], &ifr.ifr_hwaddr.sa_data, 6); + + /* get the IP of the interface we're using if this is a unicast request */ + if(unicast_hops) { + if(ioctl(sock, SIOCGIFADDR, &ifr) < 0) { + printf(_("Error: Could not determine IP-address of interface '%s'\n"), + interface_name); + exit(STATE_UNKNOWN); + } - memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); + /* cast it to avoid black pointer magic */ + my_addr = (struct sockaddr_in *)&ifr.ifr_addr; + my_ip.s_addr = my_addr->sin_addr.s_addr; + if(verbose) + printf("Pretending to be relay client %s\n", inet_ntoa(my_ip)); + } #elif defined(__bsd__) - /* King 2004 see ACKNOWLEDGEMENTS */ + /* King 2004 see ACKNOWLEDGEMENTS */ - int mib[6], len; - char *buf; - unsigned char *ptr; - struct if_msghdr *ifm; - struct sockaddr_dl *sdl; - - mib[0] = CTL_NET; - mib[1] = AF_ROUTE; - mib[2] = 0; - mib[3] = AF_LINK; - mib[4] = NET_RT_IFLIST; - - if ((mib[5] = if_nametoindex(interface_name)) == 0) { - printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno)); - exit(STATE_UNKNOWN); - } - - if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { - printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); - exit(STATE_UNKNOWN); - } - - if ((buf = malloc(len)) == NULL) { - printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); - exit(4); - } - - if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { - printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); - exit(STATE_UNKNOWN); - } - - ifm = (struct if_msghdr *)buf; - sdl = (struct sockaddr_dl *)(ifm + 1); - ptr = (unsigned char *)LLADDR(sdl); - memcpy(&client_hardware_address[0], ptr, 6) ; - /* King 2004 */ + int mib[6], len; + char *buf; + unsigned char *ptr; + struct if_msghdr *ifm; + struct sockaddr_dl *sdl; + + mib[0] = CTL_NET; + mib[1] = AF_ROUTE; + mib[2] = 0; + mib[3] = AF_LINK; + mib[4] = NET_RT_IFLIST; + + if((mib[5] = if_nametoindex(interface_name)) == 0) { + printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno)); + exit(STATE_UNKNOWN); + } + + if(sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { + printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), + interface_name, strerror(errno)); + exit(STATE_UNKNOWN); + } + + if((buf = malloc(len)) == NULL) { + printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), + interface_name, strerror(errno)); + exit(4); + } + + if(sysctl(mib, 6, buf, &len, NULL, 0) < 0) { + printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), + interface_name, strerror(errno)); + exit(STATE_UNKNOWN); + } + + ifm = (struct if_msghdr *)buf; + sdl = (struct sockaddr_dl *)(ifm + 1); + ptr = (unsigned char *)LLADDR(sdl); + memcpy(&client_hardware_address[0], ptr, 6); + /* King 2004 */ #elif defined(__sun__) || defined(__solaris__) - /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ + /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ long stat; char dev[20] = "/dev/"; char *p; int unit; - for (p = interface_name; *p && isalpha(*p); p++) - /* no-op */ ; - if ( p != '\0' ) { - 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); + for(p = interface_name; *p && isalpha(*p); p++) /* no-op */ ; + + if(p != '\0') { + 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); } stat = mac_addr_dlpi(dev, unit, client_hardware_address); - if (stat != 0) { - printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); + if(stat != 0) { + printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), + dev, unit); exit(STATE_UNKNOWN); } #elif defined(__hpux__) long stat; - char dev[20] = "/dev/dlpi" ; + char dev[20] = "/dev/dlpi"; int unit = 0; stat = mac_addr_dlpi(dev, unit, client_hardware_address); - if (stat != 0) { - printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); + if(stat != 0) { + printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), + dev, unit); exit(STATE_UNKNOWN); } - /* Kompf 2000-2003 */ + /* Kompf 2000-2003 */ #else printf(_("Error: can't get MAC address for this architecture.\n")); exit(STATE_UNKNOWN); #endif - if (verbose) { + if(verbose) { printf(_("Hardware address: ")); - for (i=0; i<6; ++i) + for(i = 0; i < 6; ++i) printf("%2.2x", client_hardware_address[i]); - printf( "\n"); + printf("\n"); } return OK; - } +} /* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ -int send_dhcp_discover(int sock){ +int +send_dhcp_discover(int sock) +{ dhcp_packet discover_packet; struct sockaddr_in sockaddr_broadcast; /* clear the packet data structure */ - bzero(&discover_packet,sizeof(discover_packet)); - + memset(&discover_packet, 0, sizeof(discover_packet)); /* boot request flag (backward compatible with BOOTP servers) */ - discover_packet.op=BOOTREQUEST; + discover_packet.op = BOOTREQUEST; /* hardware address type */ - discover_packet.htype=ETHERNET_HARDWARE_ADDRESS; + discover_packet.htype = ETH_HW_ADDR; /* length of our hardware address */ - discover_packet.hlen=ETHERNET_HARDWARE_ADDRESS_LENGTH; - - discover_packet.hops=0; + discover_packet.hlen = ETH_HW_ADDR_LEN; - /* transaction id is supposed to be random */ + /* transaction id is supposed to be random. We won't use the address so + * we don't care about high entropy here. time() is good enough */ srand(time(NULL)); - packet_xid=random(); - discover_packet.xid=htonl(packet_xid); + packet_xid = random(); + discover_packet.xid = htonl(packet_xid); /**** WHAT THE HECK IS UP WITH THIS?!? IF I DON'T MAKE THIS CALL, ONLY ONE SERVER RESPONSE IS PROCESSED!!!! ****/ /* downright bizzarre... */ ntohl(discover_packet.xid); - /*discover_packet.secs=htons(65535);*/ - discover_packet.secs=0xFF; + /*discover_packet.secs=htons(65535); */ + discover_packet.secs = 0xFF; - /* tell server it should broadcast its response */ - discover_packet.flags=htons(DHCP_BROADCAST_FLAG); + /* server needs to know if it should broadcast or unicast its response. + * 0x8000L == 32768 == 1 << 15 == broadcast, 0 == unicast */ + discover_packet.flags = unicast_hops == 0 ? htons(DHCP_BROADCAST_FLAG) : 0; /* our hardware address */ - memcpy(discover_packet.chaddr,client_hardware_address,ETHERNET_HARDWARE_ADDRESS_LENGTH); + memcpy(discover_packet.chaddr, client_hardware_address, ETH_HW_ADDR_LEN); /* first four bytes of options field is magic cookie (as per RFC 2132) */ - discover_packet.options[0]='\x63'; - discover_packet.options[1]='\x82'; - discover_packet.options[2]='\x53'; - discover_packet.options[3]='\x63'; + discover_packet.options[0] = '\x63'; + discover_packet.options[1] = '\x82'; + discover_packet.options[2] = '\x53'; + discover_packet.options[3] = '\x63'; /* DHCP message type is embedded in options field */ - discover_packet.options[4]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ - discover_packet.options[5]='\x01'; /* DHCP message option length in bytes */ - discover_packet.options[6]=DHCPDISCOVER; + discover_packet.options[4] = DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ + discover_packet.options[5] = '\x01'; /* DHCP message option length in bytes */ + discover_packet.options[6] = DHCPDISCOVER; /* the IP address we're requesting */ - if(request_specific_address==TRUE){ - discover_packet.options[7]=DHCP_OPTION_REQUESTED_ADDRESS; - discover_packet.options[8]='\x04'; - memcpy(&discover_packet.options[9],&requested_address,sizeof(requested_address)); - } - - /* send the DHCPDISCOVER packet to broadcast address */ - sockaddr_broadcast.sin_family=AF_INET; - sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT); - sockaddr_broadcast.sin_addr.s_addr=INADDR_BROADCAST; - bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); + if(request_specific_address == TRUE) { + discover_packet.options[7] = DHCP_OPTION_REQUESTED_ADDRESS; + discover_packet.options[8] = '\x04'; + memcpy(&discover_packet.options[9], &requested_address, + sizeof(requested_address)); + } + + /* unicast mods goes here */ + if(unicast_hops) + discover_packet.giaddr.s_addr = my_ip.s_addr; + discover_packet.hops = unicast_hops; - if (verbose) { - printf(_("DHCPDISCOVER to %s port %d\n"),inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); - printf("DHCPDISCOVER XID: %lu (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); - printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); - printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); - printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); - printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); + /* send the DHCPDISCOVER packet to broadcast address */ + sockaddr_broadcast.sin_family = AF_INET; + sockaddr_broadcast.sin_port = htons(DHCP_SERVER_PORT); + sockaddr_broadcast.sin_addr.s_addr = unicast_hops == 0 ? INADDR_BROADCAST : dhcp_ip.s_addr; + memset(&sockaddr_broadcast.sin_zero, 0, sizeof(sockaddr_broadcast.sin_zero)); + + + if(verbose) { + printf(_("DHCPDISCOVER to %s port %d\n"), + inet_ntoa(sockaddr_broadcast.sin_addr), + ntohs(sockaddr_broadcast.sin_port)); + printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), + ntohl(discover_packet.xid)); + printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr)); + printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr)); + printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr)); + printf("DHCDISCOVER giaddr: %s\n", inet_ntoa(discover_packet.giaddr)); } /* send the DHCPDISCOVER packet out */ - send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); + send_dhcp_packet(&discover_packet, sizeof(discover_packet), sock, + &sockaddr_broadcast); - if (verbose) - printf("\n\n"); + if(verbose) printf("\n\n"); return OK; - } - - +} /* waits for a DHCPOFFER message from one or more DHCP servers */ -int get_dhcp_offer(int sock){ +int +get_dhcp_offer(int sock) +{ dhcp_packet offer_packet; struct sockaddr_in source; - int result=OK; - int timeout=1; - int responses=0; + int result = OK; + int responses = 0; int x; - time_t start_time; + time_t dhcp_start_time; time_t current_time; - time(&start_time); + time(&dhcp_start_time); /* receive as many responses as we can */ - for(responses=0,valid_responses=0;;){ + for(responses = 0, valid_responses = 0;;) { time(¤t_time); - if((current_time-start_time)>=dhcpoffer_timeout) + if((current_time - dhcp_start_time) >= dhcpoffer_timeout) break; - if (verbose) - printf("\n\n"); + if(verbose) printf("\n\n"); - bzero(&source,sizeof(source)); - bzero(&offer_packet,sizeof(offer_packet)); + memset(&source, 0, sizeof(source)); + memset(&offer_packet, 0, sizeof(offer_packet)); - result=OK; - result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); - - if(result!=OK){ - if (verbose) - printf(_("Result=ERROR\n")); + 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) - printf(_("Result=OK\n")); - + } + else { + if(verbose) printf(_("Result=OK\n")); responses++; - } + } - if (verbose) { - printf(_("DHCPOFFER from IP address %s\n"),inet_ntoa(source.sin_addr)); - printf("DHCPOFFER XID: %lu (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); + if(verbose) { + printf(_("DHCPOFFER from IP address %s\n"), inet_ntoa(source.sin_addr)); + printf("DHCPOFFER XID: %u (0x%X)\n", ntohl(offer_packet.xid), + ntohl(offer_packet.xid)); } /* check packet xid to see if its the same as the one we used in the discover packet */ - if(ntohl(offer_packet.xid)!=packet_xid){ - if (verbose) - printf(_("DHCPOFFER XID (%lu) did not match DHCPDISCOVER XID (%lu) - ignoring packet\n"),ntohl(offer_packet.xid),packet_xid); - + if(ntohl(offer_packet.xid) != packet_xid) { + if(verbose) + printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), + ntohl(offer_packet.xid), packet_xid); continue; - } + } /* check hardware address */ - result=OK; - if (verbose) - printf("DHCPOFFER chaddr: "); - - for(x=0;x %s\n",errno,strerror(errno)); - } - return ERROR; - } - else{ - if (verbose) { - printf(_("receive_dhcp_packet() result: %d\n"),recv_result); - printf(_("receive_dhcp_packet() source: %s\n"),inet_ntoa(source_address.sin_addr)); - } + /* why do we need to peek first? i don't know, its a hack. without it, + * the source address of the first packet received was not being + * interpreted correctly. sigh... */ + memset(&source_address, 0, sizeof(source_address)); + address_size = sizeof(source_address); + recv_result = recvfrom(sock, (char *)buffer, buffer_size, MSG_PEEK, + (struct sockaddr *)&source_address, &address_size); + + if(verbose) printf("recv_result_1: %d\n", recv_result); + recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, + (struct sockaddr *)&source_address, &address_size); + + if(verbose) printf("recv_result_2: %d\n", recv_result); + + if(recv_result == -1) { + if(verbose) printf("errno: (%d) -> %s\n", errno, strerror(errno)); + return ERROR; + } + + if(verbose) { + printf(_("receive_dhcp_packet() result: %d\n"), recv_result); + printf(_("receive_dhcp_packet() source: %s\n"), + inet_ntoa(source_address.sin_addr)); + } - memcpy(address,&source_address,sizeof(source_address)); - return OK; - } - } + memcpy(address, &source_address, sizeof(source_address)); return OK; - } +} /* creates a socket for DHCP communication */ -int create_dhcp_socket(void){ - struct sockaddr_in myname; +int +create_dhcp_socket(void) +{ + struct sockaddr_in myname; struct ifreq interface; - int sock; - int flag=1; + int sock; + int flag = 1; - /* Set up the address we're going to bind to. */ - bzero(&myname,sizeof(myname)); - myname.sin_family=AF_INET; - myname.sin_port=htons(DHCP_CLIENT_PORT); - myname.sin_addr.s_addr=INADDR_ANY; /* listen on any address */ - bzero(&myname.sin_zero,sizeof(myname.sin_zero)); - - /* create a socket for DHCP communications */ - sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); - if(sock<0){ + /* Set up the address we're going to bind to. */ + memset(&myname, 0, sizeof(myname)); + memset(&myname.sin_zero, 0, sizeof(myname.sin_zero)); + myname.sin_family = AF_INET; + /* listen to dhcp server port if we're in unicast mode */ + myname.sin_port = htons(unicast_hops == 0 ? DHCP_CLIENT_PORT : DHCP_SERVER_PORT); + myname.sin_addr.s_addr = unicast_hops == 0 ? INADDR_ANY : my_ip.s_addr; + + /* create a socket for DHCP communications */ + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(sock < 0) { printf(_("Error: Could not create socket!\n")); exit(STATE_UNKNOWN); - } - - if (verbose) - printf("DHCP socket: %d\n",sock); + } - /* set the reuse address flag so we don't get errors when restarting */ - flag=1; - if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ + /* set the reuse address flag so we don't get errors when restarting */ + flag = 1; + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) { printf(_("Error: Could not set reuse address option on DHCP socket!\n")); exit(STATE_UNKNOWN); - } + } - /* 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){ + /* 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) { printf(_("Error: Could not set broadcast option on DHCP socket!\n")); exit(STATE_UNKNOWN); - } + } /* bind socket to interface */ #if defined(__linux__) - strncpy(interface.ifr_ifrn.ifrn_name,network_interface_name,IFNAMSIZ); - if(setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE,(char *)&interface,sizeof(interface))<0){ - printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"),network_interface_name); + strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ); + if(setsockopt + (sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, + sizeof(interface)) < 0) { + printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), + network_interface_name); exit(STATE_UNKNOWN); - } + } #else - strncpy(interface.ifr_name,network_interface_name,IFNAMSIZ); + strncpy(interface.ifr_name, network_interface_name, IFNAMSIZ); #endif - /* bind the socket */ - if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ - printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"),DHCP_CLIENT_PORT); + /* bind the socket */ + if(bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) { + printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), + DHCP_CLIENT_PORT); exit(STATE_UNKNOWN); - } - - return sock; - } - - -/* closes DHCP socket */ -int close_dhcp_socket(int sock){ - - close(sock); + } - return OK; - } + return sock; +} /* adds a requested server address to list in memory */ -int add_requested_server(struct in_addr server_address){ +static int +add_requested_server(struct in_addr server_address) +{ requested_server *new_server; - new_server=(requested_server *)malloc(sizeof(requested_server)); - if(new_server==NULL) + new_server = (requested_server *) malloc(sizeof(requested_server)); + if(new_server == NULL) return ERROR; - new_server->server_address=server_address; + new_server->server_address = server_address; - new_server->next=requested_server_list; - requested_server_list=new_server; + new_server->next = requested_server_list; + requested_server_list = new_server; requested_servers++; - if (verbose) - printf(_("Requested server address: %s\n"),inet_ntoa(new_server->server_address)); + if(verbose) + printf(_("Requested server address: %s\n"), + inet_ntoa(new_server->server_address)); return OK; - } +} /* adds a DHCP OFFER to list in memory */ -int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ +int +add_dhcp_offer(struct in_addr source, dhcp_packet * offer_packet) +{ dhcp_offer *new_offer; int x; int y; unsigned option_type; unsigned option_length; - if(offer_packet==NULL) - return ERROR; + if(offer_packet == NULL) return ERROR; /* process all DHCP options present in the packet */ - for(x=4;xoptions[x]==-1 || (int)offer_packet->options[x]==0) + if((int)offer_packet->options[x] == -1 || (int)offer_packet->options[x] == 0) break; /* get option type */ - option_type=offer_packet->options[x++]; + option_type = offer_packet->options[x++]; /* get option length */ - option_length=offer_packet->options[x++]; + option_length = offer_packet->options[x++]; - if (verbose) - printf("Option: %d (0x%02X)\n",option_type,option_length); + if(verbose) + printf("Option: %d (0x%02X)\n", option_type, option_length); /* get option data */ - if(option_type==DHCP_OPTION_LEASE_TIME) { - memcpy(&dhcp_lease_time, &offer_packet->options[x], - sizeof(dhcp_lease_time)); - dhcp_lease_time = ntohl(dhcp_lease_time); - } - if(option_type==DHCP_OPTION_RENEWAL_TIME) { - memcpy(&dhcp_renewal_time, &offer_packet->options[x], - sizeof(dhcp_renewal_time)); - dhcp_renewal_time = ntohl(dhcp_renewal_time); - } - if(option_type==DHCP_OPTION_REBINDING_TIME) { - memcpy(&dhcp_rebinding_time, &offer_packet->options[x], - sizeof(dhcp_rebinding_time)); - dhcp_rebinding_time = ntohl(dhcp_rebinding_time); - } + if(option_type == DHCP_OPTION_LEASE_TIME) { + memcpy(&dhcp_lease_time, &offer_packet->options[x], + sizeof(dhcp_lease_time)); + dhcp_lease_time = ntohl(dhcp_lease_time); + } + if(option_type == DHCP_OPTION_RENEWAL_TIME) { + memcpy(&dhcp_renewal_time, &offer_packet->options[x], + sizeof(dhcp_renewal_time)); + dhcp_renewal_time = ntohl(dhcp_renewal_time); + } + if(option_type == DHCP_OPTION_REBINDING_TIME) { + memcpy(&dhcp_rebinding_time, &offer_packet->options[x], + sizeof(dhcp_rebinding_time)); + dhcp_rebinding_time = ntohl(dhcp_rebinding_time); + } /* skip option data we're ignoring */ - else - for(y=0;yserver_address=source; - new_offer->offered_address=offer_packet->yiaddr; - new_offer->lease_time=dhcp_lease_time; - new_offer->renewal_time=dhcp_renewal_time; - new_offer->rebinding_time=dhcp_rebinding_time; + new_offer->server_address = source; + new_offer->offered_address = offer_packet->yiaddr; + new_offer->lease_time = dhcp_lease_time; + new_offer->renewal_time = dhcp_renewal_time; + new_offer->rebinding_time = dhcp_rebinding_time; - if (verbose) { - printf(_("Added offer from server @ %s"),inet_ntoa(new_offer->server_address)); - printf(_(" of IP address %s\n"),inet_ntoa(new_offer->offered_address)); + if(verbose) { + printf(_("Added offer from server @ %s"), + inet_ntoa(new_offer->server_address)); + printf(_(" of IP address %s\n"), inet_ntoa(new_offer->offered_address)); } /* add new offer to head of list */ - new_offer->next=dhcp_offer_list; - dhcp_offer_list=new_offer; + new_offer->next = dhcp_offer_list; + dhcp_offer_list = new_offer; return OK; - } +} /* frees memory allocated to DHCP OFFER list */ -int free_dhcp_offer_list(void){ +int +free_dhcp_offer_list(void) +{ dhcp_offer *this_offer; dhcp_offer *next_offer; - for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){ - next_offer=this_offer->next; + for(this_offer = dhcp_offer_list; this_offer != NULL; this_offer = next_offer) { + next_offer = this_offer->next; free(this_offer); - } + } return OK; - } +} /* frees memory allocated to requested server list */ -int free_requested_server_list(void){ +int +free_requested_server_list(void) +{ requested_server *this_server; requested_server *next_server; - for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){ - next_server=this_server->next; + for(this_server = requested_server_list; this_server != NULL; + this_server = next_server) { + next_server = this_server->next; free(this_server); - } - + } + return OK; - } +} /* gets state and plugin output to return */ -int get_results(void){ +int +get_results(void) +{ dhcp_offer *temp_offer; requested_server *temp_server; int result; - u_int32_t max_lease_time=0; + u_int32_t max_lease_time = 0; - received_requested_address=FALSE; + received_requested_address = FALSE; /* checks responses from requested servers */ - requested_responses=0; - if(requested_servers>0){ + requested_responses = 0; + if(requested_servers > 0) { - for(temp_server=requested_server_list;temp_server!=NULL;temp_server=temp_server->next){ + for(temp_server = requested_server_list; temp_server != NULL; + temp_server = temp_server->next) { - for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ + for(temp_offer = dhcp_offer_list; temp_offer != NULL; + temp_offer = temp_offer->next) { /* 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; - + 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(!memcmp(&requested_address, &temp_offer->offered_address, + sizeof(requested_address))) + received_requested_address = TRUE; /* see if the servers we wanted a response from talked to us or not */ - if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ - if (verbose) { - printf(_("DHCP Server Match: Offerer=%s"),inet_ntoa(temp_offer->server_address)); - printf(_(" Requested=%s\n"),inet_ntoa(temp_server->server_address)); - } + if(!memcmp(&temp_offer->server_address, &temp_server->server_address, + sizeof(temp_server->server_address))) + { + if(verbose) { + printf(_("DHCP Server Match: Offerer=%s"), + inet_ntoa(temp_offer->server_address)); + printf(_(" Requested=%s\n"), + inet_ntoa(temp_server->server_address)); + } requested_responses++; - } - } - } - - } + } + } + } + } /* else check and see if we got our requested address from any server */ - else{ - - for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ - + else { + for(temp_offer = dhcp_offer_list; temp_offer != NULL; + temp_offer = temp_offer->next) + { /* 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; - + 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; - } - } - - result=STATE_OK; - if(valid_responses==0) - result=STATE_CRITICAL; - else if(requested_servers>0 && requested_responses==0) - result=STATE_CRITICAL; - else if(requested_responsesoffered_address, + sizeof(requested_address))) + received_requested_address = TRUE; + } + } + result = STATE_OK; + if(valid_responses == 0) + result = STATE_CRITICAL; + else if(requested_servers > 0 && requested_responses == 0) + result = STATE_CRITICAL; + else if(requested_responses < requested_servers) + result = STATE_WARNING; + else if(request_specific_address == TRUE && received_requested_address == FALSE) + result = STATE_WARNING; - printf("DHCP %s: ",(result==STATE_OK)?"ok":"problem"); + printf("DHCP %s: ", (result == STATE_OK) ? "ok" : "problem"); /* we didn't receive any DHCPOFFERs */ - if(dhcp_offer_list==NULL){ + if(dhcp_offer_list == NULL) { printf(_("No DHCPOFFERs were received.\n")); return result; - } - - printf(_("Received %d DHCPOFFER(s)"),valid_responses); + } - if(requested_servers>0) - printf(_(", %s%d of %d requested servers responded"),((requested_responses0)?"only ":"",requested_responses,requested_servers); + printf(_("Received %d DHCPOFFER(s)"), valid_responses); - if(request_specific_address==TRUE) - printf(_(", requested address (%s) was %soffered"),inet_ntoa(requested_address),(received_requested_address==TRUE)?"":_("not ")); + if(requested_servers > 0) + printf(_(", %s%d of %d requested servers responded"), + ((requested_responses < requested_servers) + && requested_responses > 0) ? "only " : "", + requested_responses, + requested_servers); + + if(request_specific_address == TRUE) + printf(_(", requested address (%s) was %soffered"), + inet_ntoa(requested_address), + (received_requested_address == TRUE) ? "" : _("not ")); printf(_(", max lease time = ")); - if(max_lease_time==DHCP_INFINITE_TIME) + if(max_lease_time == DHCP_INFINITE_TIME) printf(_("Infinity")); else - printf("%lu sec",(unsigned long)max_lease_time); + printf("%lu sec", (unsigned long)max_lease_time); - printf(".\n"); + puts("."); return result; - } +} /* process command-line arguments */ -int process_arguments(int argc, char **argv){ - int c; - - if(argc<1) - return ERROR; - - c=0; - while((c+=(call_getopt(argc-c,&argv[c])))0) - dhcpoffer_timeout=atoi(optarg); + if(is_intnonneg(optarg)) + */ + if(atoi(optarg) > 0) + dhcpoffer_timeout = atoi(optarg); /* - else - usage("Time interval must be a nonnegative integer\n"); - */ + else + usage("Time interval must be a nonnegative integer\n"); + */ break; - case 'i': /* interface name */ - - strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1); - network_interface_name[sizeof(network_interface_name)-1]='\x0'; - + case 'i': /* interface name */ + strncpy(network_interface_name, optarg, + sizeof(network_interface_name) - 1); + network_interface_name[sizeof(network_interface_name) - 1] = '\x0'; break; - case 'V': /* version */ - print_revision(progname,revision); + case 'V': /* version */ + print_revision(progname, revision); exit(STATE_OK); - case 'h': /* help */ + case 'h': /* help */ print_help(); exit(STATE_OK); - case 'v': /* verbose */ - verbose=1; + case 'v': /* verbose */ + verbose++; break; - case '?': /* help */ - usage2 (_("Unknown argument"), optarg); + case '?': /* help */ + usage2(_("Unknown argument"), optarg); break; default: break; - } - } - - return i; - } + } + } + + return validate_arguments(); +} -int validate_arguments(void){ +int +validate_arguments(void) +{ return OK; - } +} #if defined(__sun__) || defined(__solaris__) || defined(__hpux__) - /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ + /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ /* get a message from a stream; return type of message */ -static int get_msg(int fd) +static int +get_msg(int fd) { - int flags = 0; - int res, ret; - ctl_area[0] = 0; - dat_area[0] = 0; - ret = 0; - res = getmsg(fd, &ctl, &dat, &flags); - - if(res < 0) { - if(errno == EINTR) { - return(GOT_INTR); - } else { - printf("%s\n", "get_msg FAILED."); - return(GOT_ERR); - } - } - if(ctl.len > 0) { - ret |= GOT_CTRL; - } - if(dat.len > 0) { - ret |= GOT_DATA; - } - return(ret); + int flags = 0; + int res, ret; + + ctl_area[0] = 0; + dat_area[0] = 0; + ret = 0; + res = getmsg(fd, &ctl, &dat, &flags); + + if(res < 0) { + if(errno == EINTR) { + return (GOT_INTR); + } + else { + printf("%s\n", "get_msg FAILED."); + return (GOT_ERR); + } + } + if(ctl.len > 0) { + ret |= GOT_CTRL; + } + if(dat.len > 0) { + ret |= GOT_DATA; + } + return (ret); } /* verify that dl_primitive in ctl_area = prim */ -static int check_ctrl(int prim) +static int +check_ctrl(int prim) { - dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area; - if(err_ack->dl_primitive != prim) { - printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), strerror(errno)); - exit(STATE_UNKNOWN); - } - return 0; + dl_error_ack_t *err_ack = (dl_error_ack_t *) ctl_area; + + if(err_ack->dl_primitive != prim) { + printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), + strerror(errno)); + exit(STATE_UNKNOWN); + } + return 0; } /* put a control message on a stream */ -static int put_ctrl(int fd, int len, int pri) +static int +put_ctrl(int fd, int len, int pri) { - ctl.len = len; - if(putmsg(fd, &ctl, 0, pri) < 0) { - printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno)); - exit(STATE_UNKNOWN); - } - return 0; + ctl.len = len; + if(putmsg(fd, &ctl, 0, pri) < 0) { + printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), + strerror(errno)); + exit(STATE_UNKNOWN); + } + + return 0; } + /* put a control + data message on a stream */ -static int put_both(int fd, int clen, int dlen, int pri) +static int +put_both(int fd, int clen, int dlen, int pri) { - ctl.len = clen; - dat.len = dlen; - if(putmsg(fd, &ctl, &dat, pri) < 0) { - printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno)); - exit(STATE_UNKNOWN); - } - return 0; + ctl.len = clen; + dat.len = dlen; + if(putmsg(fd, &ctl, &dat, pri) < 0) { + printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), + strerror(errno)); + exit(STATE_UNKNOWN); + } + + return 0; } + /* open file descriptor and attach */ -static int dl_open(const char *dev, int unit, int *fd) +static int +dl_open(const char *dev, int unit, int *fd) { - dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; - if((*fd = open(dev, O_RDWR)) == -1) { - printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno)); - exit(STATE_UNKNOWN); - } - attach_req->dl_primitive = DL_ATTACH_REQ; - attach_req->dl_ppa = unit; - put_ctrl(*fd, sizeof(dl_attach_req_t), 0); - get_msg(*fd); - return check_ctrl(DL_OK_ACK); + dl_attach_req_t *attach_req = (dl_attach_req_t *) ctl_area; + + if((*fd = open(dev, O_RDWR)) == -1) { + printf(_ + ("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), + dev, strerror(errno)); + exit(STATE_UNKNOWN); + } + attach_req->dl_primitive = DL_ATTACH_REQ; + attach_req->dl_ppa = unit; + put_ctrl(*fd, sizeof(dl_attach_req_t), 0); + get_msg(*fd); + return check_ctrl(DL_OK_ACK); } + /* send DL_BIND_REQ */ -static int dl_bind(int fd, int sap, u_char *addr) +static int +dl_bind(int fd, int sap, u_char * addr) { - dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area; - dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area; - bind_req->dl_primitive = DL_BIND_REQ; - bind_req->dl_sap = sap; - bind_req->dl_max_conind = 1; - bind_req->dl_service_mode = DL_CLDLS; - bind_req->dl_conn_mgmt = 0; - bind_req->dl_xidtest_flg = 0; - put_ctrl(fd, sizeof(dl_bind_req_t), 0); - get_msg(fd); - if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { - printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno)); - exit(STATE_UNKNOWN); - } - bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, - bind_ack->dl_addr_length); - return 0; + dl_bind_req_t *bind_req = (dl_bind_req_t *) ctl_area; + dl_bind_ack_t *bind_ack = (dl_bind_ack_t *) ctl_area; + + bind_req->dl_primitive = DL_BIND_REQ; + bind_req->dl_sap = sap; + bind_req->dl_max_conind = 1; + bind_req->dl_service_mode = DL_CLDLS; + bind_req->dl_conn_mgmt = 0; + bind_req->dl_xidtest_flg = 0; + put_ctrl(fd, sizeof(dl_bind_req_t), 0); + get_msg(fd); + if(GOT_ERR == check_ctrl(DL_BIND_ACK)) { + printf(_ + ("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), + strerror(errno)); + exit(STATE_UNKNOWN); + } + memcpy(addr, (u_char *) bind_ack + bind_ack->dl_addr_offset, + bind_ack->dl_addr_length); + return 0; } + /*********************************************************************** * interface: * function mac_addr_dlpi - get the mac address of the interface with @@ -1197,37 +1229,39 @@ * * return: 0 if OK, -1 if the address could not be determined * - * ***********************************************************************/ -long mac_addr_dlpi( const char *dev, int unit, u_char *addr) { +long +mac_addr_dlpi(const char *dev, int unit, u_char * addr) +{ int fd; u_char mac_addr[25]; - if (GOT_ERR != dl_open(dev, unit, &fd)) { - if (GOT_ERR != dl_bind(fd, INSAP, mac_addr)) { - bcopy( mac_addr, addr, 6); - return 0; - } + if(GOT_ERR != dl_open(dev, unit, &fd)) { + if(GOT_ERR != dl_bind(fd, INSAP, mac_addr)) { + memcpy(addr, mac_addr, 6); + return 0; + } } - close(fd); + close(fd); return -1; } /* Kompf 2000-2003 */ - #endif /* print usage help */ -void print_help(void){ +void +print_help(void) +{ - print_revision(progname,revision); + print_revision(progname, revision); printf("Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)\n\n"); - printf (COPYRIGHT, copyright, email); - + printf(COPYRIGHT, copyright, email); + printf(_("This plugin tests the availability of DHCP servers on a network.\n\n")); print_usage(); @@ -1241,6 +1275,8 @@ Seconds to wait for DHCPOFFER before timeout occurs\n\ -i, --interface=STRING\n\ Interface to to use for listening (i.e. eth0)\n\ + -u, --unicast=INTEGER\n\ + Unicast testing. Requires -s. Useful for testing servers on remote networks. -v, --verbose\n\ Print extra information (command-line use only)\n\ -h, --help\n\ @@ -1250,12 +1286,10 @@ } -void print_usage(void) +void +print_usage(void) { printf("\ Usage: %s [-s serverip] [-r requestedip] [-t timeout] [-i interface]\n\ - [-v]",progname); + [-v]", progname); } - - -