summaryrefslogtreecommitdiffstats
path: root/plugins-root
diff options
context:
space:
mode:
Diffstat (limited to 'plugins-root')
-rw-r--r--plugins-root/check_dhcp.c1181
1 files changed, 564 insertions, 617 deletions
diff --git a/plugins-root/check_dhcp.c b/plugins-root/check_dhcp.c
index 4b8f5e27..6802232e 100644
--- a/plugins-root/check_dhcp.c
+++ b/plugins-root/check_dhcp.c
@@ -4,7 +4,7 @@
4 * 4 *
5 * License: GPL 5 * License: GPL
6 * Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org) 6 * Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)
7 * Copyright (c) 2001-2007 Monitoring Plugins Development Team 7 * Copyright (c) 2001-2023 Monitoring Plugins Development Team
8 * 8 *
9 * Description: 9 * Description:
10 * 10 *
@@ -34,7 +34,7 @@
34 *****************************************************************************/ 34 *****************************************************************************/
35 35
36const char *progname = "check_dhcp"; 36const char *progname = "check_dhcp";
37const char *copyright = "2001-2023"; 37const char *copyright = "2001-2024";
38const char *email = "devel@monitoring-plugins.org"; 38const char *email = "devel@monitoring-plugins.org";
39 39
40#include "common.h" 40#include "common.h"
@@ -59,45 +59,45 @@ const char *email = "devel@monitoring-plugins.org";
59#include <arpa/inet.h> 59#include <arpa/inet.h>
60 60
61#if HAVE_SYS_SOCKIO_H 61#if HAVE_SYS_SOCKIO_H
62#include <sys/sockio.h> 62# include <sys/sockio.h>
63#endif // HAVE_SYS_SOCKIO_H 63#endif // HAVE_SYS_SOCKIO_H
64 64
65#if defined( __linux__ ) 65#if defined(__linux__)
66 66
67#include <linux/if_ether.h> 67# include <linux/if_ether.h>
68#include <features.h> 68# include <features.h>
69 69
70#elif defined (__bsd__) 70#elif defined(__bsd__)
71 71
72#include <netinet/if_ether.h> 72# include <netinet/if_ether.h>
73#include <sys/param.h> 73# include <sys/param.h>
74#include <sys/sysctl.h> 74# include <sys/sysctl.h>
75#include <net/if_dl.h> 75# include <net/if_dl.h>
76 76
77#elif defined(__sun__) || defined(__solaris__) || defined(__hpux__) 77#elif defined(__sun__) || defined(__solaris__) || defined(__hpux__)
78 78
79#define INSAP 22 79# define INSAP 22
80#define OUTSAP 24 80# define OUTSAP 24
81 81
82#include <signal.h> 82# include <signal.h>
83#include <ctype.h> 83# include <ctype.h>
84#include <sys/stropts.h> 84# include <sys/stropts.h>
85#include <sys/poll.h> 85# include <sys/poll.h>
86#include <sys/dlpi.h> 86# include <sys/dlpi.h>
87 87
88#define bcopy(source, destination, length) memcpy(destination, source, length) 88# define bcopy(source, destination, length) memcpy(destination, source, length)
89 89
90#define AREA_SZ 5000 /* buffer length in bytes */ 90# define AREA_SZ 5000 /* buffer length in bytes */
91static u_long ctl_area[AREA_SZ]; 91static u_long ctl_area[AREA_SZ];
92static u_long dat_area[AREA_SZ]; 92static u_long dat_area[AREA_SZ];
93static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area}; 93static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area};
94static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area}; 94static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area};
95 95
96#define GOT_CTRL 1 96# define GOT_CTRL 1
97#define GOT_DATA 2 97# define GOT_DATA 2
98#define GOT_BOTH 3 98# define GOT_BOTH 3
99#define GOT_INTR 4 99# define GOT_INTR 4
100#define GOT_ERR 128 100# define GOT_ERR 128
101 101
102static int get_msg(int); 102static int get_msg(int);
103static int check_ctrl(int); 103static int check_ctrl(int);
@@ -105,178 +105,168 @@ static int put_ctrl(int, int, int);
105static int put_both(int, int, int, int); 105static int put_both(int, int, int, int);
106static int dl_open(const char *, int, int *); 106static int dl_open(const char *, int, int *);
107static int dl_bind(int, int, u_char *); 107static int dl_bind(int, int, u_char *);
108long mac_addr_dlpi( const char *, int, u_char *); 108static long mac_addr_dlpi(const char *, int, u_char *);
109 109
110#endif // __sun__ || __solaris__ || __hpux 110#endif // __sun__ || __solaris__ || __hpux
111 111
112
113
114/**** Common definitions ****/ 112/**** Common definitions ****/
115 113
116#define OK 0 114#define OK 0
117#define ERROR -1 115#define ERROR -1
118
119 116
120/**** DHCP definitions ****/ 117/**** DHCP definitions ****/
121 118
122#define MAX_DHCP_CHADDR_LENGTH 16 119#define MAX_DHCP_CHADDR_LENGTH 16
123#define MAX_DHCP_SNAME_LENGTH 64 120#define MAX_DHCP_SNAME_LENGTH 64
124#define MAX_DHCP_FILE_LENGTH 128 121#define MAX_DHCP_FILE_LENGTH 128
125#define MAX_DHCP_OPTIONS_LENGTH 312 122#define MAX_DHCP_OPTIONS_LENGTH 312
126 123
127 124typedef struct dhcp_packet_struct {
128typedef struct dhcp_packet_struct{ 125 uint8_t op; /* packet type */
129 uint8_t op; /* packet type */ 126 uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */
130 uint8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ 127 uint8_t hlen; /* length of hardware address (of this machine) */
131 uint8_t hlen; /* length of hardware address (of this machine) */ 128 uint8_t hops; /* hops */
132 uint8_t hops; /* hops */ 129 uint32_t xid; /* random transaction id number - chosen by this machine */
133 uint32_t xid; /* random transaction id number - chosen by this machine */ 130 uint16_t secs; /* seconds used in timing */
134 uint16_t secs; /* seconds used in timing */ 131 uint16_t flags; /* flags */
135 uint16_t flags; /* flags */ 132 struct in_addr ciaddr; /* IP address of this machine (if we already have one) */
136 struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ 133 struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */
137 struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ 134 struct in_addr siaddr; /* IP address of next server */
138 struct in_addr siaddr; /* IP address of next server */ 135 struct in_addr giaddr; /* IP address of DHCP relay */
139 struct in_addr giaddr; /* IP address of DHCP relay */ 136 unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */
140 unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ 137 char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */
141 char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ 138 char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */
142 char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ 139 char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */
143 char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ 140} dhcp_packet;
144}dhcp_packet; 141
145 142typedef struct dhcp_offer_struct {
146 143 struct in_addr server_address; /* address of DHCP server that sent this offer */
147typedef struct dhcp_offer_struct{ 144 struct in_addr offered_address; /* the IP address that was offered to us */
148 struct in_addr server_address; /* address of DHCP server that sent this offer */
149 struct in_addr offered_address; /* the IP address that was offered to us */
150 uint32_t lease_time; /* lease time in seconds */ 145 uint32_t lease_time; /* lease time in seconds */
151 uint32_t renewal_time; /* renewal time in seconds */ 146 uint32_t renewal_time; /* renewal time in seconds */
152 uint32_t rebinding_time; /* rebinding time in seconds */ 147 uint32_t rebinding_time; /* rebinding time in seconds */
153 bool desired; /* is this offer desired (necessary in exclusive mode) */ 148 bool desired; /* is this offer desired (necessary in exclusive mode) */
154 struct dhcp_offer_struct *next; 149 struct dhcp_offer_struct *next;
155}dhcp_offer; 150} dhcp_offer;
156
157 151
158typedef struct requested_server_struct{ 152typedef struct requested_server_struct {
159 struct in_addr server_address; 153 struct in_addr server_address;
160 bool answered; 154 bool answered;
161 struct requested_server_struct *next; 155 struct requested_server_struct *next;
162}requested_server; 156} requested_server;
163 157
164 158#define BOOTREQUEST 1
165#define BOOTREQUEST 1 159#define BOOTREPLY 2
166#define BOOTREPLY 2 160
167 161#define DHCPDISCOVER 1
168#define DHCPDISCOVER 1 162#define DHCPOFFER 2
169#define DHCPOFFER 2 163#define DHCPREQUEST 3
170#define DHCPREQUEST 3 164#define DHCPDECLINE 4
171#define DHCPDECLINE 4 165#define DHCPACK 5
172#define DHCPACK 5 166#define DHCPNACK 6
173#define DHCPNACK 6 167#define DHCPRELEASE 7
174#define DHCPRELEASE 7 168
175 169#define DHCP_OPTION_MESSAGE_TYPE 53
176#define DHCP_OPTION_MESSAGE_TYPE 53 170#define DHCP_OPTION_HOST_NAME 12
177#define DHCP_OPTION_HOST_NAME 12 171#define DHCP_OPTION_BROADCAST_ADDRESS 28
178#define DHCP_OPTION_BROADCAST_ADDRESS 28 172#define DHCP_OPTION_REQUESTED_ADDRESS 50
179#define DHCP_OPTION_REQUESTED_ADDRESS 50 173#define DHCP_OPTION_LEASE_TIME 51
180#define DHCP_OPTION_LEASE_TIME 51 174#define DHCP_OPTION_SERVER_IDENTIFIER 54
181#define DHCP_OPTION_SERVER_IDENTIFIER 54 175#define DHCP_OPTION_RENEWAL_TIME 58
182#define DHCP_OPTION_RENEWAL_TIME 58 176#define DHCP_OPTION_REBINDING_TIME 59
183#define DHCP_OPTION_REBINDING_TIME 59 177#define DHCP_OPTION_END 255
184#define DHCP_OPTION_END 255 178
185 179#define DHCP_INFINITE_TIME 0xFFFFFFFF
186#define DHCP_INFINITE_TIME 0xFFFFFFFF
187 180
188#define DHCP_BROADCAST_FLAG 32768 181#define DHCP_BROADCAST_FLAG 32768
189 182
190#define DHCP_SERVER_PORT 67 183#define DHCP_SERVER_PORT 67
191#define DHCP_CLIENT_PORT 68 184#define DHCP_CLIENT_PORT 68
192 185
193#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ 186#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */
194#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ 187#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */
195 188
196bool unicast = false; /* unicast mode: mimic a DHCP relay */ 189static bool unicast = false; /* unicast mode: mimic a DHCP relay */
197bool exclusive = false; /* exclusive mode aka "rogue DHCP server detection" */ 190static bool exclusive = false; /* exclusive mode aka "rogue DHCP server detection" */
198struct in_addr my_ip; /* our address (required for relay) */ 191static struct in_addr my_ip; /* our address (required for relay) */
199struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ 192static struct in_addr dhcp_ip; /* server to query (if in unicast mode) */
200unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; 193static unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH] = "";
201unsigned char *user_specified_mac=NULL; 194static unsigned char *user_specified_mac = NULL;
202 195
203char network_interface_name[IFNAMSIZ]="eth0"; 196static char network_interface_name[IFNAMSIZ] = "eth0";
204 197
205uint32_t packet_xid=0; 198static uint32_t packet_xid = 0;
206 199
207uint32_t dhcp_lease_time=0; 200static uint32_t dhcp_lease_time = 0;
208uint32_t dhcp_renewal_time=0; 201static uint32_t dhcp_renewal_time = 0;
209uint32_t dhcp_rebinding_time=0; 202static uint32_t dhcp_rebinding_time = 0;
210 203
211int dhcpoffer_timeout=2; 204static int dhcpoffer_timeout = 2;
212 205
213dhcp_offer *dhcp_offer_list=NULL; 206static dhcp_offer *dhcp_offer_list = NULL;
214requested_server *requested_server_list=NULL; 207static requested_server *requested_server_list = NULL;
215 208
216int valid_responses=0; /* number of valid DHCPOFFERs we received */ 209static int valid_responses = 0; /* number of valid DHCPOFFERs we received */
217int requested_servers=0; 210static int requested_servers = 0;
218int requested_responses=0; 211static int requested_responses = 0;
219 212
220bool request_specific_address=false; 213static bool request_specific_address = false;
221bool received_requested_address=false; 214static bool received_requested_address = false;
222int verbose=0; 215static int verbose = 0;
223struct in_addr requested_address; 216static struct in_addr requested_address;
224 217
225 218static int process_arguments(int, char **);
226int process_arguments(int, char **); 219static int call_getopt(int, char **);
227int call_getopt(int, char **); 220static int validate_arguments(int);
228int validate_arguments(int);
229void print_usage(void); 221void print_usage(void);
230void print_help(void); 222static void print_help(void);
231
232void resolve_host(const char *in,struct in_addr *out);
233unsigned char *mac_aton(const char *);
234void print_hardware_address(const unsigned char *);
235int get_hardware_address(int,char *);
236int get_ip_address(int,char *);
237 223
238int send_dhcp_discover(int); 224static void resolve_host(const char *in, struct in_addr *out);
239int get_dhcp_offer(int); 225static unsigned char *mac_aton(const char *);
226static void print_hardware_address(const unsigned char *);
227static int get_hardware_address(int, char *);
228static int get_ip_address(int, char *);
240 229
241int get_results(void); 230static int send_dhcp_discover(int);
231static int get_dhcp_offer(int);
242 232
243int add_dhcp_offer(struct in_addr,dhcp_packet *); 233static int get_results(void);
244int free_dhcp_offer_list(void);
245int free_requested_server_list(void);
246 234
247int create_dhcp_socket(void); 235static int add_dhcp_offer(struct in_addr, dhcp_packet *);
248int close_dhcp_socket(int); 236static int free_dhcp_offer_list(void);
249int send_dhcp_packet(void *,int,int,struct sockaddr_in *); 237static int free_requested_server_list(void);
250int receive_dhcp_packet(void *,int,int,int,struct sockaddr_in *);
251 238
239static int create_dhcp_socket(void);
240static int close_dhcp_socket(int);
241static int send_dhcp_packet(void *, int, int, struct sockaddr_in *);
242static int receive_dhcp_packet(void *, int, int, int, struct sockaddr_in *);
252 243
253 244int main(int argc, char **argv) {
254int main(int argc, char **argv){
255 int dhcp_socket; 245 int dhcp_socket;
256 int result = STATE_UNKNOWN; 246 int result = STATE_UNKNOWN;
257 247
258 setlocale (LC_ALL, ""); 248 setlocale(LC_ALL, "");
259 bindtextdomain (PACKAGE, LOCALEDIR); 249 bindtextdomain(PACKAGE, LOCALEDIR);
260 textdomain (PACKAGE); 250 textdomain(PACKAGE);
261 251
262 /* Parse extra opts if any */ 252 /* Parse extra opts if any */
263 argv=np_extra_opts(&argc, argv, progname); 253 argv = np_extra_opts(&argc, argv, progname);
264 254
265 if(process_arguments(argc,argv)!=OK){ 255 if (process_arguments(argc, argv) != OK) {
266 usage4 (_("Could not parse arguments")); 256 usage4(_("Could not parse arguments"));
267 } 257 }
268 258
269 /* create socket for DHCP communications */ 259 /* create socket for DHCP communications */
270 dhcp_socket=create_dhcp_socket(); 260 dhcp_socket = create_dhcp_socket();
271 261
272 /* get hardware address of client machine */ 262 /* get hardware address of client machine */
273 if(user_specified_mac!=NULL) 263 if (user_specified_mac != NULL)
274 memcpy(client_hardware_address,user_specified_mac,6); 264 memcpy(client_hardware_address, user_specified_mac, 6);
275 else 265 else
276 get_hardware_address(dhcp_socket,network_interface_name); 266 get_hardware_address(dhcp_socket, network_interface_name);
277 267
278 if(unicast) /* get IP address of client machine */ 268 if (unicast) /* get IP address of client machine */
279 get_ip_address(dhcp_socket,network_interface_name); 269 get_ip_address(dhcp_socket, network_interface_name);
280 270
281 /* send DHCPDISCOVER packet */ 271 /* send DHCPDISCOVER packet */
282 send_dhcp_discover(dhcp_socket); 272 send_dhcp_discover(dhcp_socket);
@@ -288,7 +278,7 @@ int main(int argc, char **argv){
288 close_dhcp_socket(dhcp_socket); 278 close_dhcp_socket(dhcp_socket);
289 279
290 /* determine state/plugin output to return */ 280 /* determine state/plugin output to return */
291 result=get_results(); 281 result = get_results();
292 282
293 /* free allocated memory */ 283 /* free allocated memory */
294 free_dhcp_offer_list(); 284 free_dhcp_offer_list();
@@ -297,34 +287,32 @@ int main(int argc, char **argv){
297 return result; 287 return result;
298} 288}
299 289
300
301
302/* determines hardware address on client machine */ 290/* determines hardware address on client machine */
303int get_hardware_address(int sock,char *interface_name){ 291static int get_hardware_address(int sock, char *interface_name) {
304 292
305#if defined(__linux__) 293#if defined(__linux__)
306 struct ifreq ifr; 294 struct ifreq ifr;
307 295
308 strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)-1); 296 strncpy((char *)&ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1);
309 ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0'; 297 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
310 298
311 /* try and grab hardware address of requested interface */ 299 /* try and grab hardware address of requested interface */
312 if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){ 300 if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
313 printf(_("Error: Could not get hardware address of interface '%s'\n"),interface_name); 301 printf(_("Error: Could not get hardware address of interface '%s'\n"), interface_name);
314 exit(STATE_UNKNOWN); 302 exit(STATE_UNKNOWN);
315 } 303 }
316 304
317 memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); 305 memcpy(&client_hardware_address[0], &ifr.ifr_hwaddr.sa_data, 6);
318 306
319#elif defined(__bsd__) 307#elif defined(__bsd__)
320 /* King 2004 see ACKNOWLEDGEMENTS */ 308 /* King 2004 see ACKNOWLEDGEMENTS */
321 309
322 size_t len; 310 size_t len;
323 int mib[6]; 311 int mib[6];
324 char *buf; 312 char *buf;
325 unsigned char *ptr; 313 unsigned char *ptr;
326 struct if_msghdr *ifm; 314 struct if_msghdr *ifm;
327 struct sockaddr_dl *sdl; 315 struct sockaddr_dl *sdl;
328 316
329 mib[0] = CTL_NET; 317 mib[0] = CTL_NET;
330 mib[1] = AF_ROUTE; 318 mib[1] = AF_ROUTE;
@@ -332,22 +320,22 @@ int get_hardware_address(int sock,char *interface_name){
332 mib[3] = AF_LINK; 320 mib[3] = AF_LINK;
333 mib[4] = NET_RT_IFLIST; 321 mib[4] = NET_RT_IFLIST;
334 322
335 if((mib[5] = if_nametoindex(interface_name)) == 0){ 323 if ((mib[5] = if_nametoindex(interface_name)) == 0) {
336 printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno)); 324 printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno));
337 exit(STATE_UNKNOWN); 325 exit(STATE_UNKNOWN);
338 } 326 }
339 327
340 if(sysctl(mib, 6, NULL, &len, NULL, 0) < 0){ 328 if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
341 printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); 329 printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno));
342 exit(STATE_UNKNOWN); 330 exit(STATE_UNKNOWN);
343 } 331 }
344 332
345 if((buf = malloc(len)) == NULL){ 333 if ((buf = malloc(len)) == NULL) {
346 printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); 334 printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno));
347 exit(4); 335 exit(4);
348 } 336 }
349 337
350 if(sysctl(mib, 6, buf, &len, NULL, 0) < 0){ 338 if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
351 printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); 339 printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno));
352 exit(STATE_UNKNOWN); 340 exit(STATE_UNKNOWN);
353 } 341 }
@@ -355,7 +343,7 @@ int get_hardware_address(int sock,char *interface_name){
355 ifm = (struct if_msghdr *)buf; 343 ifm = (struct if_msghdr *)buf;
356 sdl = (struct sockaddr_dl *)(ifm + 1); 344 sdl = (struct sockaddr_dl *)(ifm + 1);
357 ptr = (unsigned char *)LLADDR(sdl); 345 ptr = (unsigned char *)LLADDR(sdl);
358 memcpy(&client_hardware_address[0], ptr, 6) ; 346 memcpy(&client_hardware_address[0], ptr, 6);
359 /* King 2004 */ 347 /* King 2004 */
360 348
361#elif defined(__sun__) || defined(__solaris__) 349#elif defined(__sun__) || defined(__solaris__)
@@ -368,22 +356,21 @@ int get_hardware_address(int sock,char *interface_name){
368 356
369 /* get last number from interfacename, eg lnc0, e1000g0*/ 357 /* get last number from interfacename, eg lnc0, e1000g0*/
370 int i; 358 int i;
371 p = interface_name + strlen(interface_name) -1; 359 p = interface_name + strlen(interface_name) - 1;
372 for(i = strlen(interface_name) -1; i > 0; p--) { 360 for (i = strlen(interface_name) - 1; i > 0; p--) {
373 if(isalpha(*p)) 361 if (isalpha(*p))
374 break; 362 break;
375 } 363 }
376 p++; 364 p++;
377 if( p != interface_name ){ 365 if (p != interface_name) {
378 unit = atoi(p) ; 366 unit = atoi(p);
379 strncat(dev, interface_name, 6) ; 367 strncat(dev, interface_name, 6);
380 } 368 } else {
381 else{
382 printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name); 369 printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name);
383 exit(STATE_UNKNOWN); 370 exit(STATE_UNKNOWN);
384 } 371 }
385 stat = mac_addr_dlpi(dev, unit, client_hardware_address); 372 stat = mac_addr_dlpi(dev, unit, client_hardware_address);
386 if(stat != 0){ 373 if (stat != 0) {
387 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); 374 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit);
388 exit(STATE_UNKNOWN); 375 exit(STATE_UNKNOWN);
389 } 376 }
@@ -391,11 +378,11 @@ int get_hardware_address(int sock,char *interface_name){
391#elif defined(__hpux__) 378#elif defined(__hpux__)
392 379
393 long stat; 380 long stat;
394 char dev[20] = "/dev/dlpi" ; 381 char dev[20] = "/dev/dlpi";
395 int unit = 0; 382 int unit = 0;
396 383
397 stat = mac_addr_dlpi(dev, unit, client_hardware_address); 384 stat = mac_addr_dlpi(dev, unit, client_hardware_address);
398 if(stat != 0){ 385 if (stat != 0) {
399 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); 386 printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit);
400 exit(STATE_UNKNOWN); 387 exit(STATE_UNKNOWN);
401 } 388 }
@@ -406,68 +393,65 @@ int get_hardware_address(int sock,char *interface_name){
406 exit(STATE_UNKNOWN); 393 exit(STATE_UNKNOWN);
407#endif 394#endif
408 395
409 if(verbose) 396 if (verbose)
410 print_hardware_address(client_hardware_address); 397 print_hardware_address(client_hardware_address);
411 398
412 return OK; 399 return OK;
413} 400}
414 401
415/* determines IP address of the client interface */ 402/* determines IP address of the client interface */
416int get_ip_address(int sock,char *interface_name){ 403static int get_ip_address(int sock, char *interface_name) {
417#if defined(SIOCGIFADDR) 404#if defined(SIOCGIFADDR)
418 struct ifreq ifr; 405 struct ifreq ifr;
419 406
420 strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)-1); 407 strncpy((char *)&ifr.ifr_name, interface_name, sizeof(ifr.ifr_name) - 1);
421 ifr.ifr_name[sizeof(ifr.ifr_name)-1]='\0'; 408 ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = '\0';
422 409
423 if(ioctl(sock,SIOCGIFADDR,&ifr)<0){ 410 if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
424 printf(_("Error: Cannot determine IP address of interface %s\n"), 411 printf(_("Error: Cannot determine IP address of interface %s\n"), interface_name);
425 interface_name);
426 exit(STATE_UNKNOWN); 412 exit(STATE_UNKNOWN);
427 } 413 }
428 414
429 my_ip=((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr; 415 my_ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
430 416
431#else 417#else
432 printf(_("Error: Cannot get interface IP address on this platform.\n")); 418 printf(_("Error: Cannot get interface IP address on this platform.\n"));
433 exit(STATE_UNKNOWN); 419 exit(STATE_UNKNOWN);
434#endif 420#endif
435 421
436 if(verbose) 422 if (verbose)
437 printf(_("Pretending to be relay client %s\n"),inet_ntoa(my_ip)); 423 printf(_("Pretending to be relay client %s\n"), inet_ntoa(my_ip));
438 424
439 return OK; 425 return OK;
440} 426}
441 427
442/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ 428/* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */
443int send_dhcp_discover(int sock){ 429static int send_dhcp_discover(int sock) {
444 dhcp_packet discover_packet; 430 dhcp_packet discover_packet;
445 struct sockaddr_in sockaddr_broadcast; 431 struct sockaddr_in sockaddr_broadcast;
446 unsigned short opts; 432 unsigned short opts;
447 433
448
449 /* clear the packet data structure */ 434 /* clear the packet data structure */
450 bzero(&discover_packet,sizeof(discover_packet)); 435 bzero(&discover_packet, sizeof(discover_packet));
451
452 436
453 /* boot request flag (backward compatible with BOOTP servers) */ 437 /* boot request flag (backward compatible with BOOTP servers) */
454 discover_packet.op=BOOTREQUEST; 438 discover_packet.op = BOOTREQUEST;
455 439
456 /* hardware address type */ 440 /* hardware address type */
457 discover_packet.htype=ETHERNET_HARDWARE_ADDRESS; 441 discover_packet.htype = ETHERNET_HARDWARE_ADDRESS;
458 442
459 /* length of our hardware address */ 443 /* length of our hardware address */
460 discover_packet.hlen=ETHERNET_HARDWARE_ADDRESS_LENGTH; 444 discover_packet.hlen = ETHERNET_HARDWARE_ADDRESS_LENGTH;
461 445
462 /* 446 /*
463 * transaction ID is supposed to be random. 447 * transaction ID is supposed to be random.
464 */ 448 */
465 srand(time(NULL)^getpid()); 449 srand(time(NULL) ^ getpid());
466 packet_xid=random(); 450 packet_xid = random();
467 discover_packet.xid=htonl(packet_xid); 451 discover_packet.xid = htonl(packet_xid);
468 452
469 /*discover_packet.secs=htons(65535);*/ 453 /*discover_packet.secs=htons(65535);*/
470 discover_packet.secs=0xFF; 454 discover_packet.secs = 0xFF;
471 455
472 /* 456 /*
473 * server needs to know if it should broadcast or unicast its response: 457 * server needs to know if it should broadcast or unicast its response:
@@ -476,71 +460,67 @@ int send_dhcp_discover(int sock){
476 discover_packet.flags = unicast ? 0 : htons(DHCP_BROADCAST_FLAG); 460 discover_packet.flags = unicast ? 0 : htons(DHCP_BROADCAST_FLAG);
477 461
478 /* our hardware address */ 462 /* our hardware address */
479 memcpy(discover_packet.chaddr,client_hardware_address,ETHERNET_HARDWARE_ADDRESS_LENGTH); 463 memcpy(discover_packet.chaddr, client_hardware_address, ETHERNET_HARDWARE_ADDRESS_LENGTH);
480 464
481 /* first four bytes of options field is magic cookie (as per RFC 2132) */ 465 /* first four bytes of options field is magic cookie (as per RFC 2132) */
482 discover_packet.options[0]='\x63'; 466 discover_packet.options[0] = '\x63';
483 discover_packet.options[1]='\x82'; 467 discover_packet.options[1] = '\x82';
484 discover_packet.options[2]='\x53'; 468 discover_packet.options[2] = '\x53';
485 discover_packet.options[3]='\x63'; 469 discover_packet.options[3] = '\x63';
486 470
487 opts = 4; 471 opts = 4;
488 /* DHCP message type is embedded in options field */ 472 /* DHCP message type is embedded in options field */
489 discover_packet.options[opts++]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ 473 discover_packet.options[opts++] = DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */
490 discover_packet.options[opts++]='\x01'; /* DHCP message option length in bytes */ 474 discover_packet.options[opts++] = '\x01'; /* DHCP message option length in bytes */
491 discover_packet.options[opts++]=DHCPDISCOVER; 475 discover_packet.options[opts++] = DHCPDISCOVER;
492 476
493 /* the IP address we're requesting */ 477 /* the IP address we're requesting */
494 if(request_specific_address){ 478 if (request_specific_address) {
495 discover_packet.options[opts++]=DHCP_OPTION_REQUESTED_ADDRESS; 479 discover_packet.options[opts++] = DHCP_OPTION_REQUESTED_ADDRESS;
496 discover_packet.options[opts++]='\x04'; 480 discover_packet.options[opts++] = '\x04';
497 memcpy(&discover_packet.options[opts],&requested_address,sizeof(requested_address)); 481 memcpy(&discover_packet.options[opts], &requested_address, sizeof(requested_address));
498 opts += sizeof(requested_address); 482 opts += sizeof(requested_address);
499 } 483 }
500 discover_packet.options[opts++]= (char)DHCP_OPTION_END; 484 discover_packet.options[opts++] = (char)DHCP_OPTION_END;
501 485
502 /* unicast fields */ 486 /* unicast fields */
503 if(unicast) 487 if (unicast)
504 discover_packet.giaddr.s_addr = my_ip.s_addr; 488 discover_packet.giaddr.s_addr = my_ip.s_addr;
505 489
506 /* see RFC 1542, 4.1.1 */ 490 /* see RFC 1542, 4.1.1 */
507 discover_packet.hops = unicast ? 1 : 0; 491 discover_packet.hops = unicast ? 1 : 0;
508 492
509 /* send the DHCPDISCOVER packet to broadcast address */ 493 /* send the DHCPDISCOVER packet to broadcast address */
510 sockaddr_broadcast.sin_family=AF_INET; 494 sockaddr_broadcast.sin_family = AF_INET;
511 sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT); 495 sockaddr_broadcast.sin_port = htons(DHCP_SERVER_PORT);
512 sockaddr_broadcast.sin_addr.s_addr = unicast ? dhcp_ip.s_addr : INADDR_BROADCAST; 496 sockaddr_broadcast.sin_addr.s_addr = unicast ? dhcp_ip.s_addr : INADDR_BROADCAST;
513 bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); 497 bzero(&sockaddr_broadcast.sin_zero, sizeof(sockaddr_broadcast.sin_zero));
514 498
515 499 if (verbose) {
516 if(verbose){ 500 printf(_("DHCPDISCOVER to %s port %d\n"), inet_ntoa(sockaddr_broadcast.sin_addr), ntohs(sockaddr_broadcast.sin_port));
517 printf(_("DHCPDISCOVER to %s port %d\n"),inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); 501 printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), ntohl(discover_packet.xid));
518 printf("DHCPDISCOVER XID: %u (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); 502 printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr));
519 printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); 503 printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr));
520 printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); 504 printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr));
521 printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); 505 printf("DHCDISCOVER giaddr: %s\n", inet_ntoa(discover_packet.giaddr));
522 printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr));
523 } 506 }
524 507
525 /* send the DHCPDISCOVER packet out */ 508 /* send the DHCPDISCOVER packet out */
526 send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); 509 send_dhcp_packet(&discover_packet, sizeof(discover_packet), sock, &sockaddr_broadcast);
527 510
528 if(verbose) 511 if (verbose)
529 printf("\n\n"); 512 printf("\n\n");
530 513
531 return OK; 514 return OK;
532} 515}
533 516
534
535
536
537/* waits for a DHCPOFFER message from one or more DHCP servers */ 517/* waits for a DHCPOFFER message from one or more DHCP servers */
538int get_dhcp_offer(int sock){ 518static int get_dhcp_offer(int sock) {
539 dhcp_packet offer_packet; 519 dhcp_packet offer_packet;
540 struct sockaddr_in source; 520 struct sockaddr_in source;
541 struct sockaddr_in via; 521 struct sockaddr_in via;
542 int result=OK; 522 int result = OK;
543 int responses=0; 523 int responses = 0;
544 int x; 524 int x;
545 time_t start_time; 525 time_t start_time;
546 time_t current_time; 526 time_t current_time;
@@ -548,30 +528,29 @@ int get_dhcp_offer(int sock){
548 time(&start_time); 528 time(&start_time);
549 529
550 /* receive as many responses as we can */ 530 /* receive as many responses as we can */
551 for(responses=0,valid_responses=0;;){ 531 for (responses = 0, valid_responses = 0;;) {
552 532
553 time(&current_time); 533 time(&current_time);
554 if((current_time-start_time)>=dhcpoffer_timeout) 534 if ((current_time - start_time) >= dhcpoffer_timeout)
555 break; 535 break;
556 536
557 if(verbose) 537 if (verbose)
558 printf("\n\n"); 538 printf("\n\n");
559 539
560 bzero(&source,sizeof(source)); 540 bzero(&source, sizeof(source));
561 bzero(&via,sizeof(via)); 541 bzero(&via, sizeof(via));
562 bzero(&offer_packet,sizeof(offer_packet)); 542 bzero(&offer_packet, sizeof(offer_packet));
563 543
564 result=OK; 544 result = OK;
565 result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); 545 result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, dhcpoffer_timeout, &source);
566 546
567 if(result!=OK){ 547 if (result != OK) {
568 if(verbose) 548 if (verbose)
569 printf(_("Result=ERROR\n")); 549 printf(_("Result=ERROR\n"));
570 550
571 continue; 551 continue;
572 } 552 } else {
573 else{ 553 if (verbose)
574 if(verbose)
575 printf(_("Result=OK\n")); 554 printf(_("Result=OK\n"));
576 555
577 responses++; 556 responses++;
@@ -579,85 +558,81 @@ int get_dhcp_offer(int sock){
579 558
580 /* The "source" is either a server or a relay. */ 559 /* The "source" is either a server or a relay. */
581 /* Save a copy of "source" into "via" even if it's via itself */ 560 /* Save a copy of "source" into "via" even if it's via itself */
582 memcpy(&via,&source,sizeof(source)) ; 561 memcpy(&via, &source, sizeof(source));
583 562
584 if(verbose){ 563 if (verbose) {
585 printf(_("DHCPOFFER from IP address %s"),inet_ntoa(source.sin_addr)); 564 printf(_("DHCPOFFER from IP address %s"), inet_ntoa(source.sin_addr));
586 printf(_(" via %s\n"),inet_ntoa(via.sin_addr)); 565 printf(_(" via %s\n"), inet_ntoa(via.sin_addr));
587 printf("DHCPOFFER XID: %u (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); 566 printf("DHCPOFFER XID: %u (0x%X)\n", ntohl(offer_packet.xid), ntohl(offer_packet.xid));
588 } 567 }
589 568
590 /* check packet xid to see if its the same as the one we used in the discover packet */ 569 /* check packet xid to see if its the same as the one we used in the discover packet */
591 if(ntohl(offer_packet.xid)!=packet_xid){ 570 if (ntohl(offer_packet.xid) != packet_xid) {
592 if(verbose) 571 if (verbose)
593 printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"),ntohl(offer_packet.xid),packet_xid); 572 printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), ntohl(offer_packet.xid), packet_xid);
594 573
595 continue; 574 continue;
596 } 575 }
597 576
598 /* check hardware address */ 577 /* check hardware address */
599 result=OK; 578 result = OK;
600 if(verbose) 579 if (verbose)
601 printf("DHCPOFFER chaddr: "); 580 printf("DHCPOFFER chaddr: ");
602 581
603 for(x=0;x<ETHERNET_HARDWARE_ADDRESS_LENGTH;x++){ 582 for (x = 0; x < ETHERNET_HARDWARE_ADDRESS_LENGTH; x++) {
604 if(verbose) 583 if (verbose)
605 printf("%02X",(unsigned char)offer_packet.chaddr[x]); 584 printf("%02X", (unsigned char)offer_packet.chaddr[x]);
606 585
607 if(offer_packet.chaddr[x]!=client_hardware_address[x]) 586 if (offer_packet.chaddr[x] != client_hardware_address[x])
608 result=ERROR; 587 result = ERROR;
609 } 588 }
610 if(verbose) 589 if (verbose)
611 printf("\n"); 590 printf("\n");
612 591
613 if(result==ERROR){ 592 if (result == ERROR) {
614 if(verbose) 593 if (verbose)
615 printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n")); 594 printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n"));
616 595
617 continue; 596 continue;
618 } 597 }
619 598
620 if(verbose){ 599 if (verbose) {
621 printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr)); 600 printf("DHCPOFFER ciaddr: %s\n", inet_ntoa(offer_packet.ciaddr));
622 printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr)); 601 printf("DHCPOFFER yiaddr: %s\n", inet_ntoa(offer_packet.yiaddr));
623 printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr)); 602 printf("DHCPOFFER siaddr: %s\n", inet_ntoa(offer_packet.siaddr));
624 printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr)); 603 printf("DHCPOFFER giaddr: %s\n", inet_ntoa(offer_packet.giaddr));
625 } 604 }
626 605
627 add_dhcp_offer(source.sin_addr,&offer_packet); 606 add_dhcp_offer(source.sin_addr, &offer_packet);
628 607
629 valid_responses++; 608 valid_responses++;
630 } 609 }
631 610
632 if(verbose){ 611 if (verbose) {
633 printf(_("Total responses seen on the wire: %d\n"),responses); 612 printf(_("Total responses seen on the wire: %d\n"), responses);
634 printf(_("Valid responses for this machine: %d\n"),valid_responses); 613 printf(_("Valid responses for this machine: %d\n"), valid_responses);
635 } 614 }
636 615
637 return OK; 616 return OK;
638} 617}
639 618
640
641
642/* sends a DHCP packet */ 619/* sends a DHCP packet */
643int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest){ 620static int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest) {
644 int result; 621 int result;
645 622
646 result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)dest,sizeof(*dest)); 623 result = sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, sizeof(*dest));
647 624
648 if(verbose) 625 if (verbose)
649 printf(_("send_dhcp_packet result: %d\n"),result); 626 printf(_("send_dhcp_packet result: %d\n"), result);
650 627
651 if(result<0) 628 if (result < 0)
652 return ERROR; 629 return ERROR;
653 630
654 return OK; 631 return OK;
655} 632}
656 633
657
658
659/* receives a DHCP packet */ 634/* receives a DHCP packet */
660int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address){ 635static int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address) {
661 struct timeval tv; 636 struct timeval tv;
662 fd_set readfds; 637 fd_set readfds;
663 fd_set oobfds; 638 fd_set oobfds;
@@ -666,44 +641,42 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st
666 struct sockaddr_in source_address; 641 struct sockaddr_in source_address;
667 int nfound; 642 int nfound;
668 643
669
670 /* wait for data to arrive (up time timeout) */ 644 /* wait for data to arrive (up time timeout) */
671 tv.tv_sec=timeout; 645 tv.tv_sec = timeout;
672 tv.tv_usec=0; 646 tv.tv_usec = 0;
673 FD_ZERO(&readfds); 647 FD_ZERO(&readfds);
674 FD_ZERO(&oobfds); 648 FD_ZERO(&oobfds);
675 FD_SET(sock,&readfds); 649 FD_SET(sock, &readfds);
676 FD_SET(sock,&oobfds); 650 FD_SET(sock, &oobfds);
677 nfound = select(sock+1,&readfds,NULL,&oobfds,&tv); 651 nfound = select(sock + 1, &readfds, NULL, &oobfds, &tv);
678 652
679 /* make sure some data has arrived */ 653 /* make sure some data has arrived */
680 if(!FD_ISSET(sock,&readfds)){ 654 if (!FD_ISSET(sock, &readfds)) {
681 if(verbose) 655 if (verbose)
682 printf(_("No (more) data received (nfound: %d)\n"), nfound); 656 printf(_("No (more) data received (nfound: %d)\n"), nfound);
683 return ERROR; 657 return ERROR;
684 } 658 }
685 659
686 else{ 660 else {
687 bzero(&source_address,sizeof(source_address)); 661 bzero(&source_address, sizeof(source_address));
688 address_size=sizeof(source_address); 662 address_size = sizeof(source_address);
689 recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)&source_address,&address_size); 663 recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)&source_address, &address_size);
690 if(verbose) 664 if (verbose)
691 printf("recv_result: %d\n",recv_result); 665 printf("recv_result: %d\n", recv_result);
692 666
693 if(recv_result==-1){ 667 if (recv_result == -1) {
694 if(verbose){ 668 if (verbose) {
695 printf(_("recvfrom() failed, ")); 669 printf(_("recvfrom() failed, "));
696 printf("errno: (%d) -> %s\n",errno,strerror(errno)); 670 printf("errno: (%d) -> %s\n", errno, strerror(errno));
697 } 671 }
698 return ERROR; 672 return ERROR;
699 } 673 } else {
700 else{ 674 if (verbose) {
701 if(verbose){ 675 printf(_("receive_dhcp_packet() result: %d\n"), recv_result);
702 printf(_("receive_dhcp_packet() result: %d\n"),recv_result); 676 printf(_("receive_dhcp_packet() source: %s\n"), inet_ntoa(source_address.sin_addr));
703 printf(_("receive_dhcp_packet() source: %s\n"),inet_ntoa(source_address.sin_addr));
704 } 677 }
705 678
706 memcpy(address,&source_address,sizeof(source_address)); 679 memcpy(address, &source_address, sizeof(source_address));
707 return OK; 680 return OK;
708 } 681 }
709 } 682 }
@@ -711,172 +684,166 @@ int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, st
711 return OK; 684 return OK;
712} 685}
713 686
714
715/* creates a socket for DHCP communication */ 687/* creates a socket for DHCP communication */
716int create_dhcp_socket(void){ 688static int create_dhcp_socket(void) {
717 struct sockaddr_in myname; 689 struct sockaddr_in myname;
718 struct ifreq interface; 690 struct ifreq interface;
719 int sock; 691 int sock;
720 int flag=1; 692 int flag = 1;
721 693
722 /* Set up the address we're going to bind to. */ 694 /* Set up the address we're going to bind to. */
723 bzero(&myname,sizeof(myname)); 695 bzero(&myname, sizeof(myname));
724 myname.sin_family=AF_INET; 696 myname.sin_family = AF_INET;
725 /* listen to DHCP server port if we're in unicast mode */ 697 /* listen to DHCP server port if we're in unicast mode */
726 myname.sin_port = htons(unicast ? DHCP_SERVER_PORT : DHCP_CLIENT_PORT); 698 myname.sin_port = htons(unicast ? DHCP_SERVER_PORT : DHCP_CLIENT_PORT);
727 myname.sin_addr.s_addr = unicast ? my_ip.s_addr : INADDR_ANY; 699 myname.sin_addr.s_addr = unicast ? my_ip.s_addr : INADDR_ANY;
728 bzero(&myname.sin_zero,sizeof(myname.sin_zero)); 700 bzero(&myname.sin_zero, sizeof(myname.sin_zero));
729 701
730 /* create a socket for DHCP communications */ 702 /* create a socket for DHCP communications */
731 sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); 703 sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
732 if(sock<0){ 704 if (sock < 0) {
733 printf(_("Error: Could not create socket!\n")); 705 printf(_("Error: Could not create socket!\n"));
734 exit(STATE_UNKNOWN); 706 exit(STATE_UNKNOWN);
735 } 707 }
736 708
737 if(verbose) 709 if (verbose)
738 printf("DHCP socket: %d\n",sock); 710 printf("DHCP socket: %d\n", sock);
739 711
740 /* set the reuse address flag so we don't get errors when restarting */ 712 /* set the reuse address flag so we don't get errors when restarting */
741 flag=1; 713 flag = 1;
742 if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ 714 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) {
743 printf(_("Error: Could not set reuse address option on DHCP socket!\n")); 715 printf(_("Error: Could not set reuse address option on DHCP socket!\n"));
744 exit(STATE_UNKNOWN); 716 exit(STATE_UNKNOWN);
745 } 717 }
746 718
747 /* set the broadcast option - we need this to listen to DHCP broadcast messages */ 719 /* set the broadcast option - we need this to listen to DHCP broadcast messages */
748 if(!unicast && setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){ 720 if (!unicast && setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&flag, sizeof flag) < 0) {
749 printf(_("Error: Could not set broadcast option on DHCP socket!\n")); 721 printf(_("Error: Could not set broadcast option on DHCP socket!\n"));
750 exit(STATE_UNKNOWN); 722 exit(STATE_UNKNOWN);
751 } 723 }
752 724
753 /* bind socket to interface */ 725 /* bind socket to interface */
754#if defined(__linux__) 726#if defined(__linux__)
755 strncpy(interface.ifr_ifrn.ifrn_name,network_interface_name,IFNAMSIZ-1); 727 strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ - 1);
756 interface.ifr_ifrn.ifrn_name[IFNAMSIZ-1]='\0'; 728 interface.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = '\0';
757 if(setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE,(char *)&interface,sizeof(interface))<0){ 729 if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) {
758 printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"),network_interface_name); 730 printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), network_interface_name);
759 exit(STATE_UNKNOWN); 731 exit(STATE_UNKNOWN);
760 } 732 }
761 733
762#else 734#else
763 strncpy(interface.ifr_name,network_interface_name,IFNAMSIZ-1); 735 strncpy(interface.ifr_name, network_interface_name, IFNAMSIZ - 1);
764 interface.ifr_name[IFNAMSIZ-1]='\0'; 736 interface.ifr_name[IFNAMSIZ - 1] = '\0';
765#endif 737#endif
766 738
767 /* bind the socket */ 739 /* bind the socket */
768 if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ 740 if (bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) {
769 printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"),DHCP_CLIENT_PORT); 741 printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), DHCP_CLIENT_PORT);
770 exit(STATE_UNKNOWN); 742 exit(STATE_UNKNOWN);
771 } 743 }
772 744
773 return sock; 745 return sock;
774} 746}
775 747
776
777/* closes DHCP socket */ 748/* closes DHCP socket */
778int close_dhcp_socket(int sock){ 749static int close_dhcp_socket(int sock) {
779 750
780 close(sock); 751 close(sock);
781 752
782 return OK; 753 return OK;
783} 754}
784 755
785
786/* adds a requested server address to list in memory */ 756/* adds a requested server address to list in memory */
787int add_requested_server(struct in_addr server_address){ 757static int add_requested_server(struct in_addr server_address) {
788 requested_server *new_server; 758 requested_server *new_server;
789 759
790 new_server=(requested_server *)malloc(sizeof(requested_server)); 760 new_server = (requested_server *)malloc(sizeof(requested_server));
791 if(new_server==NULL) 761 if (new_server == NULL)
792 return ERROR; 762 return ERROR;
793 763
794 new_server->server_address=server_address; 764 new_server->server_address = server_address;
795 new_server->answered=false; 765 new_server->answered = false;
796 766
797 new_server->next=requested_server_list; 767 new_server->next = requested_server_list;
798 requested_server_list=new_server; 768 requested_server_list = new_server;
799 769
800 requested_servers++; 770 requested_servers++;
801 771
802 if(verbose) 772 if (verbose)
803 printf(_("Requested server address: %s\n"),inet_ntoa(new_server->server_address)); 773 printf(_("Requested server address: %s\n"), inet_ntoa(new_server->server_address));
804 774
805 return OK; 775 return OK;
806} 776}
807 777
808
809
810
811/* adds a DHCP OFFER to list in memory */ 778/* adds a DHCP OFFER to list in memory */
812int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ 779static int add_dhcp_offer(struct in_addr source, dhcp_packet *offer_packet) {
813 dhcp_offer *new_offer; 780 dhcp_offer *new_offer;
814 int x; 781 int x;
815 unsigned option_type; 782 unsigned option_type;
816 unsigned option_length; 783 unsigned option_length;
817 struct in_addr serv_ident = {0}; 784 struct in_addr serv_ident = {0};
818 785
819 if(offer_packet==NULL) 786 if (offer_packet == NULL)
820 return ERROR; 787 return ERROR;
821 788
822 /* process all DHCP options present in the packet */ 789 /* process all DHCP options present in the packet */
823 for(x=4;x<MAX_DHCP_OPTIONS_LENGTH-1;){ 790 for (x = 4; x < MAX_DHCP_OPTIONS_LENGTH - 1;) {
824 791
825 if((int)offer_packet->options[x]==-1) 792 if ((int)offer_packet->options[x] == -1)
826 break; 793 break;
827 794
828 /* get option type */ 795 /* get option type */
829 option_type=offer_packet->options[x++]; 796 option_type = offer_packet->options[x++];
830 797
831 /* get option length */ 798 /* get option length */
832 option_length=offer_packet->options[x++]; 799 option_length = offer_packet->options[x++];
833 800
834 if(verbose) 801 if (verbose)
835 printf("Option: %d (0x%02X)\n",option_type,option_length); 802 printf("Option: %d (0x%02X)\n", option_type, option_length);
836 803
837 /* get option data */ 804 /* get option data */
838 switch(option_type){ 805 switch (option_type) {
839 case DHCP_OPTION_LEASE_TIME: 806 case DHCP_OPTION_LEASE_TIME:
840 memcpy(&dhcp_lease_time, &offer_packet->options[x],sizeof(dhcp_lease_time)); 807 memcpy(&dhcp_lease_time, &offer_packet->options[x], sizeof(dhcp_lease_time));
841 dhcp_lease_time = ntohl(dhcp_lease_time); 808 dhcp_lease_time = ntohl(dhcp_lease_time);
842 break; 809 break;
843 case DHCP_OPTION_RENEWAL_TIME: 810 case DHCP_OPTION_RENEWAL_TIME:
844 memcpy(&dhcp_renewal_time, &offer_packet->options[x],sizeof(dhcp_renewal_time)); 811 memcpy(&dhcp_renewal_time, &offer_packet->options[x], sizeof(dhcp_renewal_time));
845 dhcp_renewal_time = ntohl(dhcp_renewal_time); 812 dhcp_renewal_time = ntohl(dhcp_renewal_time);
846 break; 813 break;
847 case DHCP_OPTION_REBINDING_TIME: 814 case DHCP_OPTION_REBINDING_TIME:
848 memcpy(&dhcp_rebinding_time, &offer_packet->options[x],sizeof(dhcp_rebinding_time)); 815 memcpy(&dhcp_rebinding_time, &offer_packet->options[x], sizeof(dhcp_rebinding_time));
849 dhcp_rebinding_time = ntohl(dhcp_rebinding_time); 816 dhcp_rebinding_time = ntohl(dhcp_rebinding_time);
850 break; 817 break;
851 case DHCP_OPTION_SERVER_IDENTIFIER: 818 case DHCP_OPTION_SERVER_IDENTIFIER:
852 memcpy(&serv_ident.s_addr, &offer_packet->options[x],sizeof(serv_ident.s_addr)); 819 memcpy(&serv_ident.s_addr, &offer_packet->options[x], sizeof(serv_ident.s_addr));
853 break; 820 break;
854 } 821 }
855 822
856 /* skip option data we're ignoring */ 823 /* skip option data we're ignoring */
857 if(option_type==0) /* "pad" option, see RFC 2132 (3.1) */ 824 if (option_type == 0) /* "pad" option, see RFC 2132 (3.1) */
858 x+=1; 825 x += 1;
859 else 826 else
860 x+=option_length; 827 x += option_length;
861 } 828 }
862 829
863 if(verbose){ 830 if (verbose) {
864 if(dhcp_lease_time==DHCP_INFINITE_TIME) 831 if (dhcp_lease_time == DHCP_INFINITE_TIME)
865 printf(_("Lease Time: Infinite\n")); 832 printf(_("Lease Time: Infinite\n"));
866 else 833 else
867 printf(_("Lease Time: %lu seconds\n"),(unsigned long)dhcp_lease_time); 834 printf(_("Lease Time: %lu seconds\n"), (unsigned long)dhcp_lease_time);
868 if(dhcp_renewal_time==DHCP_INFINITE_TIME) 835 if (dhcp_renewal_time == DHCP_INFINITE_TIME)
869 printf(_("Renewal Time: Infinite\n")); 836 printf(_("Renewal Time: Infinite\n"));
870 else 837 else
871 printf(_("Renewal Time: %lu seconds\n"),(unsigned long)dhcp_renewal_time); 838 printf(_("Renewal Time: %lu seconds\n"), (unsigned long)dhcp_renewal_time);
872 if(dhcp_rebinding_time==DHCP_INFINITE_TIME) 839 if (dhcp_rebinding_time == DHCP_INFINITE_TIME)
873 printf(_("Rebinding Time: Infinite\n")); 840 printf(_("Rebinding Time: Infinite\n"));
874 printf(_("Rebinding Time: %lu seconds\n"),(unsigned long)dhcp_rebinding_time); 841 printf(_("Rebinding Time: %lu seconds\n"), (unsigned long)dhcp_rebinding_time);
875 } 842 }
876 843
877 new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer)); 844 new_offer = (dhcp_offer *)malloc(sizeof(dhcp_offer));
878 845
879 if(new_offer==NULL) 846 if (new_offer == NULL)
880 return ERROR; 847 return ERROR;
881 848
882 /* 849 /*
@@ -891,298 +858,286 @@ int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){
891 * DHCPOFFER from. If 'serv_ident' isn't available for some reason, we 858 * DHCPOFFER from. If 'serv_ident' isn't available for some reason, we
892 * use 'source'. 859 * use 'source'.
893 */ 860 */
894 new_offer->server_address=serv_ident.s_addr?serv_ident:source; 861 new_offer->server_address = serv_ident.s_addr ? serv_ident : source;
895 new_offer->offered_address=offer_packet->yiaddr; 862 new_offer->offered_address = offer_packet->yiaddr;
896 new_offer->lease_time=dhcp_lease_time; 863 new_offer->lease_time = dhcp_lease_time;
897 new_offer->renewal_time=dhcp_renewal_time; 864 new_offer->renewal_time = dhcp_renewal_time;
898 new_offer->rebinding_time=dhcp_rebinding_time; 865 new_offer->rebinding_time = dhcp_rebinding_time;
899 new_offer->desired=false; /* exclusive mode: we'll check that in get_results */ 866 new_offer->desired = false; /* exclusive mode: we'll check that in get_results */
900 867
901 868 if (verbose) {
902 if(verbose){ 869 printf(_("Added offer from server @ %s"), inet_ntoa(new_offer->server_address));
903 printf(_("Added offer from server @ %s"),inet_ntoa(new_offer->server_address)); 870 printf(_(" of IP address %s\n"), inet_ntoa(new_offer->offered_address));
904 printf(_(" of IP address %s\n"),inet_ntoa(new_offer->offered_address));
905 } 871 }
906 872
907 /* add new offer to head of list */ 873 /* add new offer to head of list */
908 new_offer->next=dhcp_offer_list; 874 new_offer->next = dhcp_offer_list;
909 dhcp_offer_list=new_offer; 875 dhcp_offer_list = new_offer;
910 876
911 return OK; 877 return OK;
912} 878}
913 879
914
915/* frees memory allocated to DHCP OFFER list */ 880/* frees memory allocated to DHCP OFFER list */
916int free_dhcp_offer_list(void){ 881static int free_dhcp_offer_list(void) {
917 dhcp_offer *this_offer; 882 dhcp_offer *this_offer;
918 dhcp_offer *next_offer; 883 dhcp_offer *next_offer;
919 884
920 for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){ 885 for (this_offer = dhcp_offer_list; this_offer != NULL; this_offer = next_offer) {
921 next_offer=this_offer->next; 886 next_offer = this_offer->next;
922 free(this_offer); 887 free(this_offer);
923 } 888 }
924 889
925 return OK; 890 return OK;
926} 891}
927 892
928
929/* frees memory allocated to requested server list */ 893/* frees memory allocated to requested server list */
930int free_requested_server_list(void){ 894static int free_requested_server_list(void) {
931 requested_server *this_server; 895 requested_server *this_server;
932 requested_server *next_server; 896 requested_server *next_server;
933 897
934 for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){ 898 for (this_server = requested_server_list; this_server != NULL; this_server = next_server) {
935 next_server=this_server->next; 899 next_server = this_server->next;
936 free(this_server); 900 free(this_server);
937 } 901 }
938 902
939 return OK; 903 return OK;
940} 904}
941 905
942
943/* gets state and plugin output to return */ 906/* gets state and plugin output to return */
944int get_results(void){ 907static int get_results(void) {
945 dhcp_offer *temp_offer, *undesired_offer=NULL; 908 dhcp_offer *temp_offer, *undesired_offer = NULL;
946 requested_server *temp_server; 909 requested_server *temp_server;
947 int result; 910 int result;
948 uint32_t max_lease_time=0; 911 uint32_t max_lease_time = 0;
949 912
950 received_requested_address=false; 913 received_requested_address = false;
951 914
952 /* checks responses from requested servers */ 915 /* checks responses from requested servers */
953 requested_responses=0; 916 requested_responses = 0;
954 if(requested_servers>0){ 917 if (requested_servers > 0) {
955 918
956 for(temp_server=requested_server_list;temp_server!=NULL;temp_server=temp_server->next){ 919 for (temp_server = requested_server_list; temp_server != NULL; temp_server = temp_server->next) {
957 920
958 for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ 921 for (temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) {
959 922
960 /* get max lease time we were offered */ 923 /* get max lease time we were offered */
961 if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) 924 if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME)
962 max_lease_time=temp_offer->lease_time; 925 max_lease_time = temp_offer->lease_time;
963 926
964 /* see if we got the address we requested */ 927 /* see if we got the address we requested */
965 if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) 928 if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address)))
966 received_requested_address=true; 929 received_requested_address = true;
967 930
968 /* see if the servers we wanted a response from talked to us or not */ 931 /* see if the servers we wanted a response from talked to us or not */
969 if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ 932 if (!memcmp(&temp_offer->server_address, &temp_server->server_address, sizeof(temp_server->server_address))) {
970 if(verbose){ 933 if (verbose) {
971 printf(_("DHCP Server Match: Offerer=%s"),inet_ntoa(temp_offer->server_address)); 934 printf(_("DHCP Server Match: Offerer=%s"), inet_ntoa(temp_offer->server_address));
972 printf(_(" Requested=%s"),inet_ntoa(temp_server->server_address)); 935 printf(_(" Requested=%s"), inet_ntoa(temp_server->server_address));
973 if(temp_server->answered) 936 if (temp_server->answered)
974 printf(_(" (duplicate)")); 937 printf(_(" (duplicate)"));
975 printf(_("\n")); 938 printf(_("\n"));
976 } 939 }
977 if(!temp_server->answered){ 940 if (!temp_server->answered) {
978 requested_responses++; 941 requested_responses++;
979 temp_server->answered=true; 942 temp_server->answered = true;
980 temp_offer->desired=true; 943 temp_offer->desired = true;
981 } 944 }
982 } 945 }
983 } 946 }
984 } 947 }
985 948
986 /* exclusive mode: check for undesired offers */ 949 /* exclusive mode: check for undesired offers */
987 for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next) { 950 for (temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) {
988 if (!temp_offer->desired) { 951 if (!temp_offer->desired) {
989 undesired_offer=temp_offer; /* Checks only for the first undesired offer */ 952 undesired_offer = temp_offer; /* Checks only for the first undesired offer */
990 break; /* no further checks needed */ 953 break; /* no further checks needed */
991 } 954 }
992 } 955 }
993 } 956 }
994 957
995 /* else check and see if we got our requested address from any server */ 958 /* else check and see if we got our requested address from any server */
996 else{ 959 else {
997 960
998 for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ 961 for (temp_offer = dhcp_offer_list; temp_offer != NULL; temp_offer = temp_offer->next) {
999 962
1000 /* get max lease time we were offered */ 963 /* get max lease time we were offered */
1001 if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) 964 if (temp_offer->lease_time > max_lease_time || temp_offer->lease_time == DHCP_INFINITE_TIME)
1002 max_lease_time=temp_offer->lease_time; 965 max_lease_time = temp_offer->lease_time;
1003 966
1004 /* see if we got the address we requested */ 967 /* see if we got the address we requested */
1005 if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) 968 if (!memcmp(&requested_address, &temp_offer->offered_address, sizeof(requested_address)))
1006 received_requested_address=true; 969 received_requested_address = true;
1007 } 970 }
1008 } 971 }
1009 972
1010 result=STATE_OK; 973 result = STATE_OK;
1011 if(valid_responses==0) 974 if (valid_responses == 0)
1012 result=STATE_CRITICAL; 975 result = STATE_CRITICAL;
1013 else if(requested_servers>0 && requested_responses==0) 976 else if (requested_servers > 0 && requested_responses == 0)
1014 result=STATE_CRITICAL; 977 result = STATE_CRITICAL;
1015 else if(requested_responses<requested_servers) 978 else if (requested_responses < requested_servers)
1016 result=STATE_WARNING; 979 result = STATE_WARNING;
1017 else if(request_specific_address && !received_requested_address) 980 else if (request_specific_address && !received_requested_address)
1018 result=STATE_WARNING; 981 result = STATE_WARNING;
1019 982
1020 if(exclusive && undesired_offer) 983 if (exclusive && undesired_offer)
1021 result=STATE_CRITICAL; 984 result = STATE_CRITICAL;
1022 985
1023 if(result==0) /* garrett honeycutt 2005 */ 986 if (result == 0) /* garrett honeycutt 2005 */
1024 printf("OK: "); 987 printf("OK: ");
1025 else if(result==1) 988 else if (result == 1)
1026 printf("WARNING: "); 989 printf("WARNING: ");
1027 else if(result==2) 990 else if (result == 2)
1028 printf("CRITICAL: "); 991 printf("CRITICAL: ");
1029 else if(result==3) 992 else if (result == 3)
1030 printf("UNKNOWN: "); 993 printf("UNKNOWN: ");
1031 994
1032 /* we didn't receive any DHCPOFFERs */ 995 /* we didn't receive any DHCPOFFERs */
1033 if(dhcp_offer_list==NULL){ 996 if (dhcp_offer_list == NULL) {
1034 printf(_("No DHCPOFFERs were received.\n")); 997 printf(_("No DHCPOFFERs were received.\n"));
1035 return result; 998 return result;
1036 } 999 }
1037 1000
1038 printf(_("Received %d DHCPOFFER(s)"),valid_responses); 1001 printf(_("Received %d DHCPOFFER(s)"), valid_responses);
1039
1040 1002
1041 if(exclusive && undesired_offer){ 1003 if (exclusive && undesired_offer) {
1042 printf(_(", Rogue DHCP Server detected! Server %s"),inet_ntoa(undesired_offer->server_address)); 1004 printf(_(", Rogue DHCP Server detected! Server %s"), inet_ntoa(undesired_offer->server_address));
1043 printf(_(" offered %s \n"),inet_ntoa(undesired_offer->offered_address)); 1005 printf(_(" offered %s \n"), inet_ntoa(undesired_offer->offered_address));
1044 return result; 1006 return result;
1045 } 1007 }
1046 1008
1047 if(requested_servers>0) 1009 if (requested_servers > 0)
1048 printf(_(", %s%d of %d requested servers responded"),((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers); 1010 printf(_(", %s%d of %d requested servers responded"), ((requested_responses < requested_servers) && requested_responses > 0) ? "only " : "", requested_responses,
1011 requested_servers);
1049 1012
1050 if(request_specific_address) 1013 if (request_specific_address)
1051 printf(_(", requested address (%s) was %soffered"),inet_ntoa(requested_address),(received_requested_address)?"":_("not ")); 1014 printf(_(", requested address (%s) was %soffered"), inet_ntoa(requested_address), (received_requested_address) ? "" : _("not "));
1052 1015
1053 printf(_(", max lease time = ")); 1016 printf(_(", max lease time = "));
1054 if(max_lease_time==DHCP_INFINITE_TIME) 1017 if (max_lease_time == DHCP_INFINITE_TIME)
1055 printf(_("Infinity")); 1018 printf(_("Infinity"));
1056 else 1019 else
1057 printf("%lu sec",(unsigned long)max_lease_time); 1020 printf("%lu sec", (unsigned long)max_lease_time);
1058 1021
1059 printf(".\n"); 1022 printf(".\n");
1060 1023
1061 return result; 1024 return result;
1062} 1025}
1063 1026
1064
1065/* process command-line arguments */ 1027/* process command-line arguments */
1066int process_arguments(int argc, char **argv){ 1028static int process_arguments(int argc, char **argv) {
1067 if(argc<1) 1029 if (argc < 1)
1068 return ERROR; 1030 return ERROR;
1069 1031
1070 call_getopt(argc,argv); 1032 call_getopt(argc, argv);
1071 return validate_arguments(argc); 1033 return validate_arguments(argc);
1072} 1034}
1073 1035
1074 1036static int call_getopt(int argc, char **argv) {
1075
1076int call_getopt(int argc, char **argv){
1077 extern int optind; 1037 extern int optind;
1078 int option_index = 0; 1038 int option_index = 0;
1079 static struct option long_options[] = 1039 static struct option long_options[] = {{"serverip", required_argument, 0, 's'},
1080 { 1040 {"requestedip", required_argument, 0, 'r'},
1081 {"serverip", required_argument,0,'s'}, 1041 {"timeout", required_argument, 0, 't'},
1082 {"requestedip", required_argument,0,'r'}, 1042 {"interface", required_argument, 0, 'i'},
1083 {"timeout", required_argument,0,'t'}, 1043 {"mac", required_argument, 0, 'm'},
1084 {"interface", required_argument,0,'i'}, 1044 {"unicast", no_argument, 0, 'u'},
1085 {"mac", required_argument,0,'m'}, 1045 {"exclusive", no_argument, 0, 'x'},
1086 {"unicast", no_argument, 0,'u'}, 1046 {"verbose", no_argument, 0, 'v'},
1087 {"exclusive", no_argument, 0,'x'}, 1047 {"version", no_argument, 0, 'V'},
1088 {"verbose", no_argument, 0,'v'}, 1048 {"help", no_argument, 0, 'h'},
1089 {"version", no_argument, 0,'V'}, 1049 {0, 0, 0, 0}};
1090 {"help", no_argument, 0,'h'}, 1050
1091 {0,0,0,0} 1051 int c = 0;
1092 }; 1052 while (true) {
1093 1053 c = getopt_long(argc, argv, "+hVvxt:s:r:t:i:m:u", long_options, &option_index);
1094 int c=0; 1054
1095 while(true){ 1055 if (c == -1 || c == EOF || c == 1)
1096 c=getopt_long(argc,argv,"+hVvxt:s:r:t:i:m:u",long_options,&option_index);
1097
1098 if(c==-1||c==EOF||c==1)
1099 break; 1056 break;
1100 1057
1101 switch(c){ 1058 switch (c) {
1102
1103 case 's': /* DHCP server address */
1104 resolve_host(optarg,&dhcp_ip);
1105 add_requested_server(dhcp_ip);
1106 break;
1107 1059
1108 case 'r': /* address we are requested from DHCP servers */ 1060 case 's': /* DHCP server address */
1109 resolve_host(optarg,&requested_address); 1061 resolve_host(optarg, &dhcp_ip);
1110 request_specific_address=true; 1062 add_requested_server(dhcp_ip);
1111 break; 1063 break;
1112 1064
1113 case 't': /* timeout */ 1065 case 'r': /* address we are requested from DHCP servers */
1066 resolve_host(optarg, &requested_address);
1067 request_specific_address = true;
1068 break;
1114 1069
1115 /* 1070 case 't': /* timeout */
1116 if(is_intnonneg(optarg)) 1071
1117 */ 1072 /*
1118 if(atoi(optarg)>0) 1073 if(is_intnonneg(optarg))
1119 dhcpoffer_timeout=atoi(optarg); 1074 */
1120 /* 1075 if (atoi(optarg) > 0)
1121 else 1076 dhcpoffer_timeout = atoi(optarg);
1122 usage("Time interval must be a nonnegative integer\n"); 1077 /*
1123 */ 1078 else
1124 break; 1079 usage("Time interval must be a nonnegative integer\n");
1080 */
1081 break;
1125 1082
1126 case 'm': /* MAC address */ 1083 case 'm': /* MAC address */
1127 1084
1128 if((user_specified_mac=mac_aton(optarg)) == NULL) 1085 if ((user_specified_mac = mac_aton(optarg)) == NULL)
1129 usage("Cannot parse MAC address.\n"); 1086 usage("Cannot parse MAC address.\n");
1130 if(verbose) 1087 if (verbose)
1131 print_hardware_address(user_specified_mac); 1088 print_hardware_address(user_specified_mac);
1132 1089
1133 break; 1090 break;
1134 1091
1135 case 'i': /* interface name */ 1092 case 'i': /* interface name */
1136 1093
1137 strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1); 1094 strncpy(network_interface_name, optarg, sizeof(network_interface_name) - 1);
1138 network_interface_name[sizeof(network_interface_name)-1]='\x0'; 1095 network_interface_name[sizeof(network_interface_name) - 1] = '\x0';
1139 1096
1140 break; 1097 break;
1141 1098
1142 case 'u': /* unicast testing */ 1099 case 'u': /* unicast testing */
1143 unicast=true; 1100 unicast = true;
1144 break; 1101 break;
1145 case 'x': /* exclusive testing aka "rogue DHCP server detection" */ 1102 case 'x': /* exclusive testing aka "rogue DHCP server detection" */
1146 exclusive=true; 1103 exclusive = true;
1147 break; 1104 break;
1148 1105
1149 case 'V': /* version */ 1106 case 'V': /* version */
1150 print_revision(progname, NP_VERSION); 1107 print_revision(progname, NP_VERSION);
1151 exit(STATE_UNKNOWN); 1108 exit(STATE_UNKNOWN);
1152 1109
1153 case 'h': /* help */ 1110 case 'h': /* help */
1154 print_help(); 1111 print_help();
1155 exit(STATE_UNKNOWN); 1112 exit(STATE_UNKNOWN);
1156 1113
1157 case 'v': /* verbose */ 1114 case 'v': /* verbose */
1158 verbose=1; 1115 verbose = 1;
1159 break; 1116 break;
1160 case '?': /* help */ 1117 case '?': /* help */
1161 usage5 (); 1118 usage5();
1162 break; 1119 break;
1163 1120
1164 default: 1121 default:
1165 break; 1122 break;
1166 } 1123 }
1167 } 1124 }
1168 return optind; 1125 return optind;
1169} 1126}
1170 1127
1128static int validate_arguments(int argc) {
1171 1129
1172int validate_arguments(int argc){ 1130 if (argc - optind > 0)
1173
1174 if(argc - optind > 0)
1175 usage(_("Got unexpected non-option argument")); 1131 usage(_("Got unexpected non-option argument"));
1176 1132
1177 return OK; 1133 return OK;
1178} 1134}
1179 1135
1180
1181#if defined(__sun__) || defined(__solaris__) || defined(__hpux__) 1136#if defined(__sun__) || defined(__solaris__) || defined(__hpux__)
1182/* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ 1137/* Kompf 2000-2003 see ACKNOWLEDGEMENTS */
1183 1138
1184/* get a message from a stream; return type of message */ 1139/* get a message from a stream; return type of message */
1185static int get_msg(int fd){ 1140static int get_msg(int fd) {
1186 int flags = 0; 1141 int flags = 0;
1187 int res, ret; 1142 int res, ret;
1188 ctl_area[0] = 0; 1143 ctl_area[0] = 0;
@@ -1190,30 +1145,29 @@ static int get_msg(int fd){
1190 ret = 0; 1145 ret = 0;
1191 res = getmsg(fd, &ctl, &dat, &flags); 1146 res = getmsg(fd, &ctl, &dat, &flags);
1192 1147
1193 if(res < 0){ 1148 if (res < 0) {
1194 if(errno == EINTR){ 1149 if (errno == EINTR) {
1195 return(GOT_INTR); 1150 return (GOT_INTR);
1196 } 1151 } else {
1197 else{
1198 printf("%s\n", "get_msg FAILED."); 1152 printf("%s\n", "get_msg FAILED.");
1199 return(GOT_ERR); 1153 return (GOT_ERR);
1200 } 1154 }
1201 } 1155 }
1202 if(ctl.len > 0){ 1156 if (ctl.len > 0) {
1203 ret |= GOT_CTRL; 1157 ret |= GOT_CTRL;
1204 } 1158 }
1205 if(dat.len > 0){ 1159 if (dat.len > 0) {
1206 ret |= GOT_DATA; 1160 ret |= GOT_DATA;
1207 } 1161 }
1208 1162
1209 return(ret); 1163 return (ret);
1210} 1164}
1211 1165
1212/* verify that dl_primitive in ctl_area = prim */ 1166/* verify that dl_primitive in ctl_area = prim */
1213static int check_ctrl(int prim){ 1167static int check_ctrl(int prim) {
1214 dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area; 1168 dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area;
1215 1169
1216 if(err_ack->dl_primitive != prim){ 1170 if (err_ack->dl_primitive != prim) {
1217 printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), strerror(errno)); 1171 printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), strerror(errno));
1218 exit(STATE_UNKNOWN); 1172 exit(STATE_UNKNOWN);
1219 } 1173 }
@@ -1222,35 +1176,35 @@ static int check_ctrl(int prim){
1222} 1176}
1223 1177
1224/* put a control message on a stream */ 1178/* put a control message on a stream */
1225static int put_ctrl(int fd, int len, int pri){ 1179static int put_ctrl(int fd, int len, int pri) {
1226 1180
1227 ctl.len = len; 1181 ctl.len = len;
1228 if(putmsg(fd, &ctl, 0, pri) < 0){ 1182 if (putmsg(fd, &ctl, 0, pri) < 0) {
1229 printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno)); 1183 printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno));
1230 exit(STATE_UNKNOWN); 1184 exit(STATE_UNKNOWN);
1231 } 1185 }
1232 1186
1233 return 0; 1187 return 0;
1234} 1188}
1235 1189
1236/* put a control + data message on a stream */ 1190/* put a control + data message on a stream */
1237static int put_both(int fd, int clen, int dlen, int pri){ 1191static int put_both(int fd, int clen, int dlen, int pri) {
1238 1192
1239 ctl.len = clen; 1193 ctl.len = clen;
1240 dat.len = dlen; 1194 dat.len = dlen;
1241 if(putmsg(fd, &ctl, &dat, pri) < 0){ 1195 if (putmsg(fd, &ctl, &dat, pri) < 0) {
1242 printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno)); 1196 printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno));
1243 exit(STATE_UNKNOWN); 1197 exit(STATE_UNKNOWN);
1244 } 1198 }
1245 1199
1246 return 0; 1200 return 0;
1247} 1201}
1248 1202
1249/* open file descriptor and attach */ 1203/* open file descriptor and attach */
1250static int dl_open(const char *dev, int unit, int *fd){ 1204static int dl_open(const char *dev, int unit, int *fd) {
1251 dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; 1205 dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area;
1252 1206
1253 if((*fd = open(dev, O_RDWR)) == -1){ 1207 if ((*fd = open(dev, O_RDWR)) == -1) {
1254 printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno)); 1208 printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno));
1255 exit(STATE_UNKNOWN); 1209 exit(STATE_UNKNOWN);
1256 } 1210 }
@@ -1262,7 +1216,7 @@ static int dl_open(const char *dev, int unit, int *fd){
1262} 1216}
1263 1217
1264/* send DL_BIND_REQ */ 1218/* send DL_BIND_REQ */
1265static int dl_bind(int fd, int sap, u_char *addr){ 1219static int dl_bind(int fd, int sap, u_char *addr) {
1266 dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area; 1220 dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area;
1267 dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area; 1221 dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area;
1268 1222
@@ -1274,12 +1228,11 @@ static int dl_bind(int fd, int sap, u_char *addr){
1274 bind_req->dl_xidtest_flg = 0; 1228 bind_req->dl_xidtest_flg = 0;
1275 put_ctrl(fd, sizeof(dl_bind_req_t), 0); 1229 put_ctrl(fd, sizeof(dl_bind_req_t), 0);
1276 get_msg(fd); 1230 get_msg(fd);
1277 if (GOT_ERR == check_ctrl(DL_BIND_ACK)){ 1231 if (GOT_ERR == check_ctrl(DL_BIND_ACK)) {
1278 printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno)); 1232 printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno));
1279 exit(STATE_UNKNOWN); 1233 exit(STATE_UNKNOWN);
1280 } 1234 }
1281 bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, 1235 bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, bind_ack->dl_addr_length);
1282 bind_ack->dl_addr_length);
1283 1236
1284 return 0; 1237 return 0;
1285} 1238}
@@ -1296,13 +1249,13 @@ static int dl_bind(int fd, int sap, u_char *addr){
1296 * 1249 *
1297 ***********************************************************************/ 1250 ***********************************************************************/
1298 1251
1299long mac_addr_dlpi( const char *dev, int unit, u_char *addr){ 1252static long mac_addr_dlpi(const char *dev, int unit, u_char *addr) {
1300 int fd; 1253 int fd;
1301 u_char mac_addr[25]; 1254 u_char mac_addr[25];
1302 1255
1303 if(GOT_ERR != dl_open(dev, unit, &fd)){ 1256 if (GOT_ERR != dl_open(dev, unit, &fd)) {
1304 if(GOT_ERR != dl_bind(fd, INSAP, mac_addr)){ 1257 if (GOT_ERR != dl_bind(fd, INSAP, mac_addr)) {
1305 bcopy( mac_addr, addr, 6); 1258 bcopy(mac_addr, addr, 6);
1306 return 0; 1259 return 0;
1307 } 1260 }
1308 } 1261 }
@@ -1314,99 +1267,93 @@ long mac_addr_dlpi( const char *dev, int unit, u_char *addr){
1314/* Kompf 2000-2003 */ 1267/* Kompf 2000-2003 */
1315#endif 1268#endif
1316 1269
1317
1318/* resolve host name or die (TODO: move this to netutils.c!) */ 1270/* resolve host name or die (TODO: move this to netutils.c!) */
1319void resolve_host(const char *in,struct in_addr *out){ 1271static void resolve_host(const char *in, struct in_addr *out) {
1320 struct addrinfo hints, *ai; 1272 struct addrinfo hints, *ai;
1321 1273
1322 memset(&hints,0,sizeof(hints)); 1274 memset(&hints, 0, sizeof(hints));
1323 hints.ai_family=PF_INET; 1275 hints.ai_family = PF_INET;
1324 if (getaddrinfo(in,NULL,&hints,&ai) != 0) 1276 if (getaddrinfo(in, NULL, &hints, &ai) != 0)
1325 usage_va(_("Invalid hostname/address - %s"),optarg); 1277 usage_va(_("Invalid hostname/address - %s"), optarg);
1326 1278
1327 memcpy(out,&((struct sockaddr_in *)ai->ai_addr)->sin_addr,sizeof(*out)); 1279 memcpy(out, &((struct sockaddr_in *)ai->ai_addr)->sin_addr, sizeof(*out));
1328 freeaddrinfo(ai); 1280 freeaddrinfo(ai);
1329} 1281}
1330 1282
1331
1332/* parse MAC address string, return 6 bytes (unterminated) or NULL */ 1283/* parse MAC address string, return 6 bytes (unterminated) or NULL */
1333unsigned char *mac_aton(const char *string){ 1284static unsigned char *mac_aton(const char *string) {
1334 static unsigned char result[6]; 1285 static unsigned char result[6];
1335 char tmp[3]; 1286 char tmp[3];
1336 unsigned i, j; 1287 unsigned i, j;
1337 1288
1338 for(i=0, j=0; string[i] != '\0' && j < sizeof(result); i++){ 1289 for (i = 0, j = 0; string[i] != '\0' && j < sizeof(result); i++) {
1339 /* ignore ':' and any other non-hex character */ 1290 /* ignore ':' and any other non-hex character */
1340 if(!isxdigit(string[i]) || !isxdigit(string[i+1])) 1291 if (!isxdigit(string[i]) || !isxdigit(string[i + 1]))
1341 continue; 1292 continue;
1342 tmp[0]=string[i]; 1293 tmp[0] = string[i];
1343 tmp[1]=string[i+1]; 1294 tmp[1] = string[i + 1];
1344 tmp[2]='\0'; 1295 tmp[2] = '\0';
1345 result[j]=strtol(tmp,(char **)NULL,16); 1296 result[j] = strtol(tmp, (char **)NULL, 16);
1346 i++; 1297 i++;
1347 j++; 1298 j++;
1348 } 1299 }
1349 1300
1350 return (j==6) ? result : NULL; 1301 return (j == 6) ? result : NULL;
1351} 1302}
1352 1303
1353 1304static void print_hardware_address(const unsigned char *address) {
1354void print_hardware_address(const unsigned char *address){
1355 int i; 1305 int i;
1356 1306
1357 printf(_("Hardware address: ")); 1307 printf(_("Hardware address: "));
1358 for (i=0; i<5; i++) 1308 for (i = 0; i < 5; i++)
1359 printf("%2.2x:", address[i]); 1309 printf("%2.2x:", address[i]);
1360 printf("%2.2x", address[i]); 1310 printf("%2.2x", address[i]);
1361 putchar('\n'); 1311 putchar('\n');
1362} 1312}
1363 1313
1364
1365/* print usage help */ 1314/* print usage help */
1366void print_help(void){ 1315static void print_help(void) {
1367 1316
1368 print_revision(progname, NP_VERSION); 1317 print_revision(progname, NP_VERSION);
1369 1318
1370 printf("Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)\n"); 1319 printf("Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)\n");
1371 printf (COPYRIGHT, copyright, email); 1320 printf(COPYRIGHT, copyright, email);
1372 1321
1373 printf("%s\n", _("This plugin tests the availability of DHCP servers on a network.")); 1322 printf("%s\n", _("This plugin tests the availability of DHCP servers on a network."));
1374 1323
1375 printf ("\n\n"); 1324 printf("\n\n");
1376 1325
1377 print_usage(); 1326 print_usage();
1378 1327
1379 printf (UT_HELP_VRSN); 1328 printf(UT_HELP_VRSN);
1380 printf (UT_EXTRA_OPTS); 1329 printf(UT_EXTRA_OPTS);
1381 1330
1382 printf (UT_VERBOSE); 1331 printf(UT_VERBOSE);
1383 1332
1384 printf (" %s\n", "-s, --serverip=IPADDRESS"); 1333 printf(" %s\n", "-s, --serverip=IPADDRESS");
1385 printf (" %s\n", _("IP address of DHCP server that we must hear from")); 1334 printf(" %s\n", _("IP address of DHCP server that we must hear from"));
1386 printf (" %s\n", "-r, --requestedip=IPADDRESS"); 1335 printf(" %s\n", "-r, --requestedip=IPADDRESS");
1387 printf (" %s\n", _("IP address that should be offered by at least one DHCP server")); 1336 printf(" %s\n", _("IP address that should be offered by at least one DHCP server"));
1388 printf (" %s\n", "-t, --timeout=INTEGER"); 1337 printf(" %s\n", "-t, --timeout=INTEGER");
1389 printf (" %s\n", _("Seconds to wait for DHCPOFFER before timeout occurs")); 1338 printf(" %s\n", _("Seconds to wait for DHCPOFFER before timeout occurs"));
1390 printf (" %s\n", "-i, --interface=STRING"); 1339 printf(" %s\n", "-i, --interface=STRING");
1391 printf (" %s\n", _("Interface to to use for listening (i.e. eth0)")); 1340 printf(" %s\n", _("Interface to to use for listening (i.e. eth0)"));
1392 printf (" %s\n", "-m, --mac=STRING"); 1341 printf(" %s\n", "-m, --mac=STRING");
1393 printf (" %s\n", _("MAC address to use in the DHCP request")); 1342 printf(" %s\n", _("MAC address to use in the DHCP request"));
1394 printf (" %s\n", "-u, --unicast"); 1343 printf(" %s\n", "-u, --unicast");
1395 printf (" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s")); 1344 printf(" %s\n", _("Unicast testing: mimic a DHCP relay, requires -s"));
1396 printf (" %s\n", "-x, --exclusive"); 1345 printf(" %s\n", "-x, --exclusive");
1397 printf (" %s\n", _("Only requested DHCP server may response (rogue DHCP server detection), requires -s")); 1346 printf(" %s\n", _("Only requested DHCP server may response (rogue DHCP server detection), requires -s"));
1398 1347
1399 printf (UT_SUPPORT); 1348 printf(UT_SUPPORT);
1400 return; 1349 return;
1401} 1350}
1402 1351
1352void print_usage(void) {
1403 1353
1404void 1354 printf("%s\n", _("Usage:"));
1405print_usage(void){ 1355 printf(" %s [-v] [-u] [-x] [-s serverip] [-r requestedip] [-t timeout]\n", progname);
1406 1356 printf(" [-i interface] [-m mac]\n");
1407 printf ("%s\n", _("Usage:"));
1408 printf (" %s [-v] [-u] [-x] [-s serverip] [-r requestedip] [-t timeout]\n",progname);
1409 printf (" [-i interface] [-m mac]\n");
1410 1357
1411 return; 1358 return;
1412} 1359}