diff options
Diffstat (limited to 'web/attachments/137903-nagiosplug-check_dhcp-unicast.diff')
-rw-r--r-- | web/attachments/137903-nagiosplug-check_dhcp-unicast.diff | 1894 |
1 files changed, 1894 insertions, 0 deletions
diff --git a/web/attachments/137903-nagiosplug-check_dhcp-unicast.diff b/web/attachments/137903-nagiosplug-check_dhcp-unicast.diff new file mode 100644 index 0000000..693de0f --- /dev/null +++ b/web/attachments/137903-nagiosplug-check_dhcp-unicast.diff | |||
@@ -0,0 +1,1894 @@ | |||
1 | --- ../nplg/plugins/check_dhcp.c 2005-01-28 15:00:58.000000000 +0100 | ||
2 | +++ ./plugins/check_dhcp.c 2005-06-08 15:28:58.000000000 +0200 | ||
3 | @@ -22,12 +22,18 @@ | ||
4 | * along with this program; if not, write to the Free Software | ||
5 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
6 | * | ||
7 | -* $Id: check_dhcp.c,v 1.7 2005/01/25 18:11:21 harpermann Exp $ | ||
8 | +*-------------------------------------------------------------------------- | ||
9 | +* Unicast mode was originally implemented by Heiti of Boras Kommun with | ||
10 | +* general improvements as well as usability fixes and "forward"-porting by | ||
11 | +* Andreas Ericsson of OP5 AB. | ||
12 | +*-------------------------------------------------------------------------- | ||
13 | +* | ||
14 | +* $Id: check_dhcp.c,v 1.9 2005/06/07 15:57:53 exon Exp $ | ||
15 | * | ||
16 | *****************************************************************************/ | ||
17 | |||
18 | const char *progname = "check_dhcp"; | ||
19 | -const char *revision = "$Revision: 1.7 $"; | ||
20 | +const char *revision = "$Revision: 1.9 $"; | ||
21 | const char *copyright = "2001-2004"; | ||
22 | const char *email = "nagiosplug-devel@lists.sourceforge.net"; | ||
23 | |||
24 | @@ -64,8 +70,8 @@ | ||
25 | |||
26 | #elif defined(__sun__) || defined(__solaris__) || defined(__hpux__) | ||
27 | |||
28 | -#define INSAP 22 | ||
29 | -#define OUTSAP 24 | ||
30 | +#define INSAP 22 | ||
31 | +#define OUTSAP 24 | ||
32 | |||
33 | #include <signal.h> | ||
34 | #include <ctype.h> | ||
35 | @@ -73,19 +79,17 @@ | ||
36 | #include <sys/poll.h> | ||
37 | #include <sys/dlpi.h> | ||
38 | |||
39 | -#define bcopy(source, destination, length) memcpy(destination, source, length) | ||
40 | - | ||
41 | -#define AREA_SZ 5000 /* buffer length in bytes */ | ||
42 | +#define AREA_SZ 5000 /* buffer length in bytes */ | ||
43 | static u_long ctl_area[AREA_SZ]; | ||
44 | static u_long dat_area[AREA_SZ]; | ||
45 | -static struct strbuf ctl = {AREA_SZ, 0, (char *)ctl_area}; | ||
46 | -static struct strbuf dat = {AREA_SZ, 0, (char *)dat_area}; | ||
47 | +static struct strbuf ctl = { AREA_SZ, 0, (char *)ctl_area }; | ||
48 | +static struct strbuf dat = { AREA_SZ, 0, (char *)dat_area }; | ||
49 | |||
50 | -#define GOT_CTRL 1 | ||
51 | -#define GOT_DATA 2 | ||
52 | -#define GOT_BOTH 3 | ||
53 | -#define GOT_INTR 4 | ||
54 | -#define GOT_ERR 128 | ||
55 | +#define GOT_CTRL 1 | ||
56 | +#define GOT_DATA 2 | ||
57 | +#define GOT_BOTH 3 | ||
58 | +#define GOT_INTR 4 | ||
59 | +#define GOT_ERR 128 | ||
60 | |||
61 | #define u_int8_t uint8_t | ||
62 | #define u_int16_t uint16_t | ||
63 | @@ -97,26 +101,11 @@ | ||
64 | static int put_both(int, int, int, int); | ||
65 | static int dl_open(const char *, int, int *); | ||
66 | static int dl_bind(int, int, u_char *); | ||
67 | -long mac_addr_dlpi( const char *, int, u_char *); | ||
68 | +static long mac_addr_dlpi(const char *, int, u_char *); | ||
69 | |||
70 | #endif | ||
71 | |||
72 | -#define HAVE_GETOPT_H | ||
73 | - | ||
74 | - | ||
75 | -/**** Common definitions ****/ | ||
76 | - | ||
77 | -#define STATE_OK 0 | ||
78 | -#define STATE_WARNING 1 | ||
79 | -#define STATE_CRITICAL 2 | ||
80 | -#define STATE_UNKNOWN -1 | ||
81 | - | ||
82 | -#define OK 0 | ||
83 | -#define ERROR -1 | ||
84 | - | ||
85 | -#define FALSE 0 | ||
86 | -#define TRUE 1 | ||
87 | - | ||
88 | +static int add_requested_server(struct in_addr server_address); | ||
89 | |||
90 | /**** DHCP definitions ****/ | ||
91 | |||
92 | @@ -126,39 +115,39 @@ | ||
93 | #define MAX_DHCP_OPTIONS_LENGTH 312 | ||
94 | |||
95 | |||
96 | -typedef struct dhcp_packet_struct{ | ||
97 | - u_int8_t op; /* packet type */ | ||
98 | - u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ | ||
99 | - u_int8_t hlen; /* length of hardware address (of this machine) */ | ||
100 | - u_int8_t hops; /* hops */ | ||
101 | - u_int32_t xid; /* random transaction id number - chosen by this machine */ | ||
102 | - u_int16_t secs; /* seconds used in timing */ | ||
103 | - u_int16_t flags; /* flags */ | ||
104 | - struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ | ||
105 | - struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ | ||
106 | - struct in_addr siaddr; /* IP address of DHCP server */ | ||
107 | - struct in_addr giaddr; /* IP address of DHCP relay */ | ||
108 | - unsigned char chaddr [MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ | ||
109 | - char sname [MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ | ||
110 | - char file [MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ | ||
111 | - char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ | ||
112 | - }dhcp_packet; | ||
113 | - | ||
114 | - | ||
115 | -typedef struct dhcp_offer_struct{ | ||
116 | - struct in_addr server_address; /* address of DHCP server that sent this offer */ | ||
117 | - struct in_addr offered_address; /* the IP address that was offered to us */ | ||
118 | - u_int32_t lease_time; /* lease time in seconds */ | ||
119 | - u_int32_t renewal_time; /* renewal time in seconds */ | ||
120 | - u_int32_t rebinding_time; /* rebinding time in seconds */ | ||
121 | +typedef struct dhcp_packet_struct { | ||
122 | + u_int8_t op; /* packet type */ | ||
123 | + u_int8_t htype; /* type of hardware address for this machine (Ethernet, etc) */ | ||
124 | + u_int8_t hlen; /* length of hardware address (of this machine) */ | ||
125 | + u_int8_t hops; /* hops */ | ||
126 | + u_int32_t xid; /* random transaction id number - chosen by this machine */ | ||
127 | + u_int16_t secs; /* seconds used in timing */ | ||
128 | + u_int16_t flags; /* flags */ | ||
129 | + struct in_addr ciaddr; /* IP address of this machine (if we already have one) */ | ||
130 | + struct in_addr yiaddr; /* IP address of this machine (offered by the DHCP server) */ | ||
131 | + struct in_addr siaddr; /* IP address of DHCP server */ | ||
132 | + struct in_addr giaddr; /* IP address of DHCP relay */ | ||
133 | + unsigned char chaddr[MAX_DHCP_CHADDR_LENGTH]; /* hardware address of this machine */ | ||
134 | + char sname[MAX_DHCP_SNAME_LENGTH]; /* name of DHCP server */ | ||
135 | + char file[MAX_DHCP_FILE_LENGTH]; /* boot file name (used for diskless booting?) */ | ||
136 | + char options[MAX_DHCP_OPTIONS_LENGTH]; /* options */ | ||
137 | +} dhcp_packet; | ||
138 | + | ||
139 | + | ||
140 | +typedef struct dhcp_offer_struct { | ||
141 | + struct in_addr server_address; /* address of DHCP server that sent this offer */ | ||
142 | + struct in_addr offered_address; /* the IP address that was offered to us */ | ||
143 | + u_int32_t lease_time; /* lease time in seconds */ | ||
144 | + u_int32_t renewal_time; /* renewal time in seconds */ | ||
145 | + u_int32_t rebinding_time; /* rebinding time in seconds */ | ||
146 | struct dhcp_offer_struct *next; | ||
147 | - }dhcp_offer; | ||
148 | +} dhcp_offer; | ||
149 | |||
150 | |||
151 | -typedef struct requested_server_struct{ | ||
152 | +typedef struct requested_server_struct { | ||
153 | struct in_addr server_address; | ||
154 | struct requested_server_struct *next; | ||
155 | - }requested_server; | ||
156 | +} requested_server; | ||
157 | |||
158 | |||
159 | #define BOOTREQUEST 1 | ||
160 | @@ -183,35 +172,40 @@ | ||
161 | #define DHCP_INFINITE_TIME 0xFFFFFFFF | ||
162 | |||
163 | #define DHCP_BROADCAST_FLAG 32768 | ||
164 | +#define DHCP_UNICAST_FLAG 0 | ||
165 | |||
166 | #define DHCP_SERVER_PORT 67 | ||
167 | #define DHCP_CLIENT_PORT 68 | ||
168 | |||
169 | -#define ETHERNET_HARDWARE_ADDRESS 1 /* used in htype field of dhcp packet */ | ||
170 | -#define ETHERNET_HARDWARE_ADDRESS_LENGTH 6 /* length of Ethernet hardware addresses */ | ||
171 | +#define ETH_HW_ADDR 1 /* used in htype field of dhcp packet */ | ||
172 | +#define ETH_HW_ADDR_LEN 6 /* length of Ethernet hardware addresses */ | ||
173 | |||
174 | -unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH]=""; | ||
175 | +u_int8_t unicast_hops = 0; /* number of hops for unicast dhcp */ | ||
176 | +struct in_addr my_ip; /* our address (required for relay) */ | ||
177 | +struct in_addr dhcp_ip; /* server to query (if in unicast mode) */ | ||
178 | +struct sockaddr_in *my_addr; /* used to obtain our address */ | ||
179 | +unsigned char client_hardware_address[MAX_DHCP_CHADDR_LENGTH] = ""; | ||
180 | |||
181 | -char network_interface_name[8]="eth0"; | ||
182 | +char network_interface_name[8] = "eth0"; | ||
183 | |||
184 | -u_int32_t packet_xid=0; | ||
185 | +u_int32_t packet_xid = 0; | ||
186 | |||
187 | -u_int32_t dhcp_lease_time=0; | ||
188 | -u_int32_t dhcp_renewal_time=0; | ||
189 | -u_int32_t dhcp_rebinding_time=0; | ||
190 | +u_int32_t dhcp_lease_time = 0; | ||
191 | +u_int32_t dhcp_renewal_time = 0; | ||
192 | +u_int32_t dhcp_rebinding_time = 0; | ||
193 | |||
194 | -int dhcpoffer_timeout=2; | ||
195 | +int dhcpoffer_timeout = 2; | ||
196 | |||
197 | -dhcp_offer *dhcp_offer_list=NULL; | ||
198 | -requested_server *requested_server_list=NULL; | ||
199 | +dhcp_offer *dhcp_offer_list = NULL; | ||
200 | +requested_server *requested_server_list = NULL; | ||
201 | |||
202 | -int valid_responses=0; /* number of valid DHCPOFFERs we received */ | ||
203 | -int requested_servers=0; | ||
204 | -int requested_responses=0; | ||
205 | +int valid_responses = 0; /* number of valid DHCPOFFERs we received */ | ||
206 | +int requested_servers = 0; | ||
207 | +int requested_responses = 0; | ||
208 | |||
209 | -int request_specific_address=FALSE; | ||
210 | -int received_requested_address=FALSE; | ||
211 | -int verbose=0; | ||
212 | +int request_specific_address = FALSE; | ||
213 | +int received_requested_address = FALSE; | ||
214 | +int verbose = 0; | ||
215 | struct in_addr requested_address; | ||
216 | |||
217 | |||
218 | @@ -221,41 +215,42 @@ | ||
219 | void print_usage(void); | ||
220 | void print_help(void); | ||
221 | |||
222 | -int get_hardware_address(int,char *); | ||
223 | +int get_hardware_address(int, char *); | ||
224 | |||
225 | int send_dhcp_discover(int); | ||
226 | int get_dhcp_offer(int); | ||
227 | |||
228 | int get_results(void); | ||
229 | |||
230 | -int add_dhcp_offer(struct in_addr,dhcp_packet *); | ||
231 | +int add_dhcp_offer(struct in_addr, dhcp_packet *); | ||
232 | int free_dhcp_offer_list(void); | ||
233 | int free_requested_server_list(void); | ||
234 | |||
235 | int create_dhcp_socket(void); | ||
236 | -int close_dhcp_socket(int); | ||
237 | -int send_dhcp_packet(void *,int,int,struct sockaddr_in *); | ||
238 | -int receive_dhcp_packet(void *,int,int,int,struct sockaddr_in *); | ||
239 | +int send_dhcp_packet(void *, int, int, struct sockaddr_in *); | ||
240 | +int receive_dhcp_packet(void *, int, int, int, struct sockaddr_in *); | ||
241 | |||
242 | |||
243 | |||
244 | -int main(int argc, char **argv){ | ||
245 | +int | ||
246 | +main(int argc, char **argv) | ||
247 | +{ | ||
248 | int dhcp_socket; | ||
249 | int result; | ||
250 | |||
251 | - setlocale (LC_ALL, ""); | ||
252 | - bindtextdomain (PACKAGE, LOCALEDIR); | ||
253 | - textdomain (PACKAGE); | ||
254 | - | ||
255 | - if(process_arguments(argc,argv)!=OK){ | ||
256 | - usage4 (_("Could not parse arguments")); | ||
257 | - } | ||
258 | + setlocale(LC_ALL, ""); | ||
259 | + bindtextdomain(PACKAGE, LOCALEDIR); | ||
260 | + textdomain(PACKAGE); | ||
261 | + | ||
262 | + if(process_arguments(argc, argv) != OK) { | ||
263 | + usage4(_("Could not parse arguments")); | ||
264 | + } | ||
265 | |||
266 | /* create socket for DHCP communications */ | ||
267 | - dhcp_socket=create_dhcp_socket(); | ||
268 | + dhcp_socket = create_dhcp_socket(); | ||
269 | |||
270 | /* get hardware address of client machine */ | ||
271 | - get_hardware_address(dhcp_socket,network_interface_name); | ||
272 | + get_hardware_address(dhcp_socket, network_interface_name); | ||
273 | |||
274 | /* send DHCPDISCOVER packet */ | ||
275 | send_dhcp_discover(dhcp_socket); | ||
276 | @@ -264,930 +259,967 @@ | ||
277 | get_dhcp_offer(dhcp_socket); | ||
278 | |||
279 | /* close socket we created */ | ||
280 | - close_dhcp_socket(dhcp_socket); | ||
281 | + close(dhcp_socket); | ||
282 | |||
283 | /* determine state/plugin output to return */ | ||
284 | - result=get_results(); | ||
285 | + result = get_results(); | ||
286 | |||
287 | /* free allocated memory */ | ||
288 | free_dhcp_offer_list(); | ||
289 | free_requested_server_list(); | ||
290 | |||
291 | return result; | ||
292 | - } | ||
293 | - | ||
294 | +} | ||
295 | |||
296 | |||
297 | /* determines hardware address on client machine */ | ||
298 | -int get_hardware_address(int sock,char *interface_name){ | ||
299 | - | ||
300 | +int | ||
301 | +get_hardware_address(int sock, char *interface_name) | ||
302 | +{ | ||
303 | int i; | ||
304 | |||
305 | #if defined(__linux__) | ||
306 | struct ifreq ifr; | ||
307 | |||
308 | - strncpy((char *)&ifr.ifr_name,interface_name,sizeof(ifr.ifr_name)); | ||
309 | - | ||
310 | + strncpy((char *)&ifr.ifr_name, interface_name, sizeof(ifr.ifr_name)); | ||
311 | + | ||
312 | /* try and grab hardware address of requested interface */ | ||
313 | - if(ioctl(sock,SIOCGIFHWADDR,&ifr)<0){ | ||
314 | - printf(_("Error: Could not get hardware address of interface '%s'\n"),interface_name); | ||
315 | + if(ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) { | ||
316 | + printf(_("Error: Could not get hardware address of interface '%s'\n"), | ||
317 | + interface_name); | ||
318 | exit(STATE_UNKNOWN); | ||
319 | - } | ||
320 | + } | ||
321 | + memcpy(&client_hardware_address[0], &ifr.ifr_hwaddr.sa_data, 6); | ||
322 | + | ||
323 | + /* get the IP of the interface we're using if this is a unicast request */ | ||
324 | + if(unicast_hops) { | ||
325 | + if(ioctl(sock, SIOCGIFADDR, &ifr) < 0) { | ||
326 | + printf(_("Error: Could not determine IP-address of interface '%s'\n"), | ||
327 | + interface_name); | ||
328 | + exit(STATE_UNKNOWN); | ||
329 | + } | ||
330 | |||
331 | - memcpy(&client_hardware_address[0],&ifr.ifr_hwaddr.sa_data,6); | ||
332 | + /* cast it to avoid black pointer magic */ | ||
333 | + my_addr = (struct sockaddr_in *)&ifr.ifr_addr; | ||
334 | + my_ip.s_addr = my_addr->sin_addr.s_addr; | ||
335 | + if(verbose) | ||
336 | + printf("Pretending to be relay client %s\n", inet_ntoa(my_ip)); | ||
337 | + } | ||
338 | |||
339 | #elif defined(__bsd__) | ||
340 | - /* King 2004 see ACKNOWLEDGEMENTS */ | ||
341 | + /* King 2004 see ACKNOWLEDGEMENTS */ | ||
342 | |||
343 | - int mib[6], len; | ||
344 | - char *buf; | ||
345 | - unsigned char *ptr; | ||
346 | - struct if_msghdr *ifm; | ||
347 | - struct sockaddr_dl *sdl; | ||
348 | - | ||
349 | - mib[0] = CTL_NET; | ||
350 | - mib[1] = AF_ROUTE; | ||
351 | - mib[2] = 0; | ||
352 | - mib[3] = AF_LINK; | ||
353 | - mib[4] = NET_RT_IFLIST; | ||
354 | - | ||
355 | - if ((mib[5] = if_nametoindex(interface_name)) == 0) { | ||
356 | - printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno)); | ||
357 | - exit(STATE_UNKNOWN); | ||
358 | - } | ||
359 | - | ||
360 | - if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { | ||
361 | - printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), interface_name, strerror(errno)); | ||
362 | - exit(STATE_UNKNOWN); | ||
363 | - } | ||
364 | - | ||
365 | - if ((buf = malloc(len)) == NULL) { | ||
366 | - printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), interface_name, strerror(errno)); | ||
367 | - exit(4); | ||
368 | - } | ||
369 | - | ||
370 | - if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { | ||
371 | - printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), interface_name, strerror(errno)); | ||
372 | - exit(STATE_UNKNOWN); | ||
373 | - } | ||
374 | - | ||
375 | - ifm = (struct if_msghdr *)buf; | ||
376 | - sdl = (struct sockaddr_dl *)(ifm + 1); | ||
377 | - ptr = (unsigned char *)LLADDR(sdl); | ||
378 | - memcpy(&client_hardware_address[0], ptr, 6) ; | ||
379 | - /* King 2004 */ | ||
380 | + int mib[6], len; | ||
381 | + char *buf; | ||
382 | + unsigned char *ptr; | ||
383 | + struct if_msghdr *ifm; | ||
384 | + struct sockaddr_dl *sdl; | ||
385 | + | ||
386 | + mib[0] = CTL_NET; | ||
387 | + mib[1] = AF_ROUTE; | ||
388 | + mib[2] = 0; | ||
389 | + mib[3] = AF_LINK; | ||
390 | + mib[4] = NET_RT_IFLIST; | ||
391 | + | ||
392 | + if((mib[5] = if_nametoindex(interface_name)) == 0) { | ||
393 | + printf(_("Error: if_nametoindex error - %s.\n"), strerror(errno)); | ||
394 | + exit(STATE_UNKNOWN); | ||
395 | + } | ||
396 | + | ||
397 | + if(sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { | ||
398 | + printf(_("Error: Couldn't get hardware address from %s. sysctl 1 error - %s.\n"), | ||
399 | + interface_name, strerror(errno)); | ||
400 | + exit(STATE_UNKNOWN); | ||
401 | + } | ||
402 | + | ||
403 | + if((buf = malloc(len)) == NULL) { | ||
404 | + printf(_("Error: Couldn't get hardware address from interface %s. malloc error - %s.\n"), | ||
405 | + interface_name, strerror(errno)); | ||
406 | + exit(4); | ||
407 | + } | ||
408 | + | ||
409 | + if(sysctl(mib, 6, buf, &len, NULL, 0) < 0) { | ||
410 | + printf(_("Error: Couldn't get hardware address from %s. sysctl 2 error - %s.\n"), | ||
411 | + interface_name, strerror(errno)); | ||
412 | + exit(STATE_UNKNOWN); | ||
413 | + } | ||
414 | + | ||
415 | + ifm = (struct if_msghdr *)buf; | ||
416 | + sdl = (struct sockaddr_dl *)(ifm + 1); | ||
417 | + ptr = (unsigned char *)LLADDR(sdl); | ||
418 | + memcpy(&client_hardware_address[0], ptr, 6); | ||
419 | + /* King 2004 */ | ||
420 | |||
421 | #elif defined(__sun__) || defined(__solaris__) | ||
422 | |||
423 | - /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ | ||
424 | + /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ | ||
425 | long stat; | ||
426 | char dev[20] = "/dev/"; | ||
427 | char *p; | ||
428 | int unit; | ||
429 | |||
430 | - for (p = interface_name; *p && isalpha(*p); p++) | ||
431 | - /* no-op */ ; | ||
432 | - if ( p != '\0' ) { | ||
433 | - unit = atoi(p) ; | ||
434 | - *p = '\0' ; | ||
435 | - strncat(dev, interface_name, 6) ; | ||
436 | - } else { | ||
437 | - printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), interface_name); | ||
438 | + for(p = interface_name; *p && isalpha(*p); p++) /* no-op */ ; | ||
439 | + | ||
440 | + if(p != '\0') { | ||
441 | + unit = atoi(p); | ||
442 | + *p = '\0'; | ||
443 | + strncat(dev, interface_name, 6); | ||
444 | + } | ||
445 | + else { | ||
446 | + printf(_("Error: can't find unit number in interface_name (%s) - expecting TypeNumber eg lnc0.\n"), | ||
447 | + interface_name); | ||
448 | exit(STATE_UNKNOWN); | ||
449 | } | ||
450 | stat = mac_addr_dlpi(dev, unit, client_hardware_address); | ||
451 | - if (stat != 0) { | ||
452 | - printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); | ||
453 | + if(stat != 0) { | ||
454 | + printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), | ||
455 | + dev, unit); | ||
456 | exit(STATE_UNKNOWN); | ||
457 | } | ||
458 | |||
459 | #elif defined(__hpux__) | ||
460 | |||
461 | long stat; | ||
462 | - char dev[20] = "/dev/dlpi" ; | ||
463 | + char dev[20] = "/dev/dlpi"; | ||
464 | int unit = 0; | ||
465 | |||
466 | stat = mac_addr_dlpi(dev, unit, client_hardware_address); | ||
467 | - if (stat != 0) { | ||
468 | - printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), dev, unit); | ||
469 | + if(stat != 0) { | ||
470 | + printf(_("Error: can't read MAC address from DLPI streams interface for device %s unit %d.\n"), | ||
471 | + dev, unit); | ||
472 | exit(STATE_UNKNOWN); | ||
473 | } | ||
474 | - /* Kompf 2000-2003 */ | ||
475 | + /* Kompf 2000-2003 */ | ||
476 | |||
477 | #else | ||
478 | printf(_("Error: can't get MAC address for this architecture.\n")); | ||
479 | exit(STATE_UNKNOWN); | ||
480 | #endif | ||
481 | |||
482 | - if (verbose) { | ||
483 | + if(verbose) { | ||
484 | printf(_("Hardware address: ")); | ||
485 | - for (i=0; i<6; ++i) | ||
486 | + for(i = 0; i < 6; ++i) | ||
487 | printf("%2.2x", client_hardware_address[i]); | ||
488 | - printf( "\n"); | ||
489 | + printf("\n"); | ||
490 | } | ||
491 | |||
492 | return OK; | ||
493 | - } | ||
494 | +} | ||
495 | |||
496 | |||
497 | /* sends a DHCPDISCOVER broadcast message in an attempt to find DHCP servers */ | ||
498 | -int send_dhcp_discover(int sock){ | ||
499 | +int | ||
500 | +send_dhcp_discover(int sock) | ||
501 | +{ | ||
502 | dhcp_packet discover_packet; | ||
503 | struct sockaddr_in sockaddr_broadcast; | ||
504 | |||
505 | |||
506 | /* clear the packet data structure */ | ||
507 | - bzero(&discover_packet,sizeof(discover_packet)); | ||
508 | - | ||
509 | + memset(&discover_packet, 0, sizeof(discover_packet)); | ||
510 | |||
511 | /* boot request flag (backward compatible with BOOTP servers) */ | ||
512 | - discover_packet.op=BOOTREQUEST; | ||
513 | + discover_packet.op = BOOTREQUEST; | ||
514 | |||
515 | /* hardware address type */ | ||
516 | - discover_packet.htype=ETHERNET_HARDWARE_ADDRESS; | ||
517 | + discover_packet.htype = ETH_HW_ADDR; | ||
518 | |||
519 | /* length of our hardware address */ | ||
520 | - discover_packet.hlen=ETHERNET_HARDWARE_ADDRESS_LENGTH; | ||
521 | - | ||
522 | - discover_packet.hops=0; | ||
523 | + discover_packet.hlen = ETH_HW_ADDR_LEN; | ||
524 | |||
525 | - /* transaction id is supposed to be random */ | ||
526 | + /* transaction id is supposed to be random. We won't use the address so | ||
527 | + * we don't care about high entropy here. time() is good enough */ | ||
528 | srand(time(NULL)); | ||
529 | - packet_xid=random(); | ||
530 | - discover_packet.xid=htonl(packet_xid); | ||
531 | + packet_xid = random(); | ||
532 | + discover_packet.xid = htonl(packet_xid); | ||
533 | |||
534 | /**** WHAT THE HECK IS UP WITH THIS?!? IF I DON'T MAKE THIS CALL, ONLY ONE SERVER RESPONSE IS PROCESSED!!!! ****/ | ||
535 | /* downright bizzarre... */ | ||
536 | ntohl(discover_packet.xid); | ||
537 | |||
538 | - /*discover_packet.secs=htons(65535);*/ | ||
539 | - discover_packet.secs=0xFF; | ||
540 | + /*discover_packet.secs=htons(65535); */ | ||
541 | + discover_packet.secs = 0xFF; | ||
542 | |||
543 | - /* tell server it should broadcast its response */ | ||
544 | - discover_packet.flags=htons(DHCP_BROADCAST_FLAG); | ||
545 | + /* server needs to know if it should broadcast or unicast its response. | ||
546 | + * 0x8000L == 32768 == 1 << 15 == broadcast, 0 == unicast */ | ||
547 | + discover_packet.flags = unicast_hops == 0 ? htons(DHCP_BROADCAST_FLAG) : 0; | ||
548 | |||
549 | /* our hardware address */ | ||
550 | - memcpy(discover_packet.chaddr,client_hardware_address,ETHERNET_HARDWARE_ADDRESS_LENGTH); | ||
551 | + memcpy(discover_packet.chaddr, client_hardware_address, ETH_HW_ADDR_LEN); | ||
552 | |||
553 | /* first four bytes of options field is magic cookie (as per RFC 2132) */ | ||
554 | - discover_packet.options[0]='\x63'; | ||
555 | - discover_packet.options[1]='\x82'; | ||
556 | - discover_packet.options[2]='\x53'; | ||
557 | - discover_packet.options[3]='\x63'; | ||
558 | + discover_packet.options[0] = '\x63'; | ||
559 | + discover_packet.options[1] = '\x82'; | ||
560 | + discover_packet.options[2] = '\x53'; | ||
561 | + discover_packet.options[3] = '\x63'; | ||
562 | |||
563 | /* DHCP message type is embedded in options field */ | ||
564 | - discover_packet.options[4]=DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ | ||
565 | - discover_packet.options[5]='\x01'; /* DHCP message option length in bytes */ | ||
566 | - discover_packet.options[6]=DHCPDISCOVER; | ||
567 | + discover_packet.options[4] = DHCP_OPTION_MESSAGE_TYPE; /* DHCP message type option identifier */ | ||
568 | + discover_packet.options[5] = '\x01'; /* DHCP message option length in bytes */ | ||
569 | + discover_packet.options[6] = DHCPDISCOVER; | ||
570 | |||
571 | /* the IP address we're requesting */ | ||
572 | - if(request_specific_address==TRUE){ | ||
573 | - discover_packet.options[7]=DHCP_OPTION_REQUESTED_ADDRESS; | ||
574 | - discover_packet.options[8]='\x04'; | ||
575 | - memcpy(&discover_packet.options[9],&requested_address,sizeof(requested_address)); | ||
576 | - } | ||
577 | - | ||
578 | - /* send the DHCPDISCOVER packet to broadcast address */ | ||
579 | - sockaddr_broadcast.sin_family=AF_INET; | ||
580 | - sockaddr_broadcast.sin_port=htons(DHCP_SERVER_PORT); | ||
581 | - sockaddr_broadcast.sin_addr.s_addr=INADDR_BROADCAST; | ||
582 | - bzero(&sockaddr_broadcast.sin_zero,sizeof(sockaddr_broadcast.sin_zero)); | ||
583 | + if(request_specific_address == TRUE) { | ||
584 | + discover_packet.options[7] = DHCP_OPTION_REQUESTED_ADDRESS; | ||
585 | + discover_packet.options[8] = '\x04'; | ||
586 | + memcpy(&discover_packet.options[9], &requested_address, | ||
587 | + sizeof(requested_address)); | ||
588 | + } | ||
589 | + | ||
590 | + /* unicast mods goes here */ | ||
591 | + if(unicast_hops) | ||
592 | + discover_packet.giaddr.s_addr = my_ip.s_addr; | ||
593 | |||
594 | + discover_packet.hops = unicast_hops; | ||
595 | |||
596 | - if (verbose) { | ||
597 | - printf(_("DHCPDISCOVER to %s port %d\n"),inet_ntoa(sockaddr_broadcast.sin_addr),ntohs(sockaddr_broadcast.sin_port)); | ||
598 | - printf("DHCPDISCOVER XID: %lu (0x%X)\n",ntohl(discover_packet.xid),ntohl(discover_packet.xid)); | ||
599 | - printf("DHCDISCOVER ciaddr: %s\n",inet_ntoa(discover_packet.ciaddr)); | ||
600 | - printf("DHCDISCOVER yiaddr: %s\n",inet_ntoa(discover_packet.yiaddr)); | ||
601 | - printf("DHCDISCOVER siaddr: %s\n",inet_ntoa(discover_packet.siaddr)); | ||
602 | - printf("DHCDISCOVER giaddr: %s\n",inet_ntoa(discover_packet.giaddr)); | ||
603 | + /* send the DHCPDISCOVER packet to broadcast address */ | ||
604 | + sockaddr_broadcast.sin_family = AF_INET; | ||
605 | + sockaddr_broadcast.sin_port = htons(DHCP_SERVER_PORT); | ||
606 | + sockaddr_broadcast.sin_addr.s_addr = unicast_hops == 0 ? INADDR_BROADCAST : dhcp_ip.s_addr; | ||
607 | + memset(&sockaddr_broadcast.sin_zero, 0, sizeof(sockaddr_broadcast.sin_zero)); | ||
608 | + | ||
609 | + | ||
610 | + if(verbose) { | ||
611 | + printf(_("DHCPDISCOVER to %s port %d\n"), | ||
612 | + inet_ntoa(sockaddr_broadcast.sin_addr), | ||
613 | + ntohs(sockaddr_broadcast.sin_port)); | ||
614 | + printf("DHCPDISCOVER XID: %u (0x%X)\n", ntohl(discover_packet.xid), | ||
615 | + ntohl(discover_packet.xid)); | ||
616 | + printf("DHCDISCOVER ciaddr: %s\n", inet_ntoa(discover_packet.ciaddr)); | ||
617 | + printf("DHCDISCOVER yiaddr: %s\n", inet_ntoa(discover_packet.yiaddr)); | ||
618 | + printf("DHCDISCOVER siaddr: %s\n", inet_ntoa(discover_packet.siaddr)); | ||
619 | + printf("DHCDISCOVER giaddr: %s\n", inet_ntoa(discover_packet.giaddr)); | ||
620 | } | ||
621 | |||
622 | /* send the DHCPDISCOVER packet out */ | ||
623 | - send_dhcp_packet(&discover_packet,sizeof(discover_packet),sock,&sockaddr_broadcast); | ||
624 | + send_dhcp_packet(&discover_packet, sizeof(discover_packet), sock, | ||
625 | + &sockaddr_broadcast); | ||
626 | |||
627 | - if (verbose) | ||
628 | - printf("\n\n"); | ||
629 | + if(verbose) printf("\n\n"); | ||
630 | |||
631 | return OK; | ||
632 | - } | ||
633 | - | ||
634 | - | ||
635 | +} | ||
636 | |||
637 | |||
638 | /* waits for a DHCPOFFER message from one or more DHCP servers */ | ||
639 | -int get_dhcp_offer(int sock){ | ||
640 | +int | ||
641 | +get_dhcp_offer(int sock) | ||
642 | +{ | ||
643 | dhcp_packet offer_packet; | ||
644 | struct sockaddr_in source; | ||
645 | - int result=OK; | ||
646 | - int timeout=1; | ||
647 | - int responses=0; | ||
648 | + int result = OK; | ||
649 | + int responses = 0; | ||
650 | int x; | ||
651 | - time_t start_time; | ||
652 | + time_t dhcp_start_time; | ||
653 | time_t current_time; | ||
654 | |||
655 | - time(&start_time); | ||
656 | + time(&dhcp_start_time); | ||
657 | |||
658 | /* receive as many responses as we can */ | ||
659 | - for(responses=0,valid_responses=0;;){ | ||
660 | + for(responses = 0, valid_responses = 0;;) { | ||
661 | |||
662 | time(¤t_time); | ||
663 | - if((current_time-start_time)>=dhcpoffer_timeout) | ||
664 | + if((current_time - dhcp_start_time) >= dhcpoffer_timeout) | ||
665 | break; | ||
666 | |||
667 | - if (verbose) | ||
668 | - printf("\n\n"); | ||
669 | + if(verbose) printf("\n\n"); | ||
670 | |||
671 | - bzero(&source,sizeof(source)); | ||
672 | - bzero(&offer_packet,sizeof(offer_packet)); | ||
673 | + memset(&source, 0, sizeof(source)); | ||
674 | + memset(&offer_packet, 0, sizeof(offer_packet)); | ||
675 | |||
676 | - result=OK; | ||
677 | - result=receive_dhcp_packet(&offer_packet,sizeof(offer_packet),sock,dhcpoffer_timeout,&source); | ||
678 | - | ||
679 | - if(result!=OK){ | ||
680 | - if (verbose) | ||
681 | - printf(_("Result=ERROR\n")); | ||
682 | + result = OK; | ||
683 | + result = receive_dhcp_packet(&offer_packet, sizeof(offer_packet), sock, | ||
684 | + dhcpoffer_timeout, &source); | ||
685 | |||
686 | + if(result != OK) { | ||
687 | + if(verbose) printf(_("Result=ERROR\n")); | ||
688 | continue; | ||
689 | - } | ||
690 | - else{ | ||
691 | - if (verbose) | ||
692 | - printf(_("Result=OK\n")); | ||
693 | - | ||
694 | + } | ||
695 | + else { | ||
696 | + if(verbose) printf(_("Result=OK\n")); | ||
697 | responses++; | ||
698 | - } | ||
699 | + } | ||
700 | |||
701 | - if (verbose) { | ||
702 | - printf(_("DHCPOFFER from IP address %s\n"),inet_ntoa(source.sin_addr)); | ||
703 | - printf("DHCPOFFER XID: %lu (0x%X)\n",ntohl(offer_packet.xid),ntohl(offer_packet.xid)); | ||
704 | + if(verbose) { | ||
705 | + printf(_("DHCPOFFER from IP address %s\n"), inet_ntoa(source.sin_addr)); | ||
706 | + printf("DHCPOFFER XID: %u (0x%X)\n", ntohl(offer_packet.xid), | ||
707 | + ntohl(offer_packet.xid)); | ||
708 | } | ||
709 | |||
710 | /* check packet xid to see if its the same as the one we used in the discover packet */ | ||
711 | - if(ntohl(offer_packet.xid)!=packet_xid){ | ||
712 | - if (verbose) | ||
713 | - printf(_("DHCPOFFER XID (%lu) did not match DHCPDISCOVER XID (%lu) - ignoring packet\n"),ntohl(offer_packet.xid),packet_xid); | ||
714 | - | ||
715 | + if(ntohl(offer_packet.xid) != packet_xid) { | ||
716 | + if(verbose) | ||
717 | + printf(_("DHCPOFFER XID (%u) did not match DHCPDISCOVER XID (%u) - ignoring packet\n"), | ||
718 | + ntohl(offer_packet.xid), packet_xid); | ||
719 | continue; | ||
720 | - } | ||
721 | + } | ||
722 | |||
723 | /* check hardware address */ | ||
724 | - result=OK; | ||
725 | - if (verbose) | ||
726 | - printf("DHCPOFFER chaddr: "); | ||
727 | - | ||
728 | - for(x=0;x<ETHERNET_HARDWARE_ADDRESS_LENGTH;x++){ | ||
729 | - if (verbose) | ||
730 | - printf("%02X",(unsigned char)offer_packet.chaddr[x]); | ||
731 | + result = OK; | ||
732 | + if(verbose) printf("DHCPOFFER chaddr: "); | ||
733 | |||
734 | - if(offer_packet.chaddr[x]!=client_hardware_address[x]) | ||
735 | - result=ERROR; | ||
736 | + for(x = 0; x < ETH_HW_ADDR_LEN; x++) { | ||
737 | + if(verbose) printf("%02X", (unsigned char)offer_packet.chaddr[x]); | ||
738 | + if(offer_packet.chaddr[x] != client_hardware_address[x]) | ||
739 | + result = ERROR; | ||
740 | } | ||
741 | - if (verbose) | ||
742 | - printf("\n"); | ||
743 | + if(verbose) printf("\n"); | ||
744 | |||
745 | - if(result==ERROR){ | ||
746 | - if (verbose) | ||
747 | + if(result == ERROR) { | ||
748 | + if(verbose) | ||
749 | printf(_("DHCPOFFER hardware address did not match our own - ignoring packet\n")); | ||
750 | - | ||
751 | continue; | ||
752 | - } | ||
753 | + } | ||
754 | |||
755 | - if (verbose) { | ||
756 | - printf("DHCPOFFER ciaddr: %s\n",inet_ntoa(offer_packet.ciaddr)); | ||
757 | - printf("DHCPOFFER yiaddr: %s\n",inet_ntoa(offer_packet.yiaddr)); | ||
758 | - printf("DHCPOFFER siaddr: %s\n",inet_ntoa(offer_packet.siaddr)); | ||
759 | - printf("DHCPOFFER giaddr: %s\n",inet_ntoa(offer_packet.giaddr)); | ||
760 | + if(verbose) { | ||
761 | + printf("DHCPOFFER ciaddr: %s\n", inet_ntoa(offer_packet.ciaddr)); | ||
762 | + printf("DHCPOFFER yiaddr: %s\n", inet_ntoa(offer_packet.yiaddr)); | ||
763 | + printf("DHCPOFFER siaddr: %s\n", inet_ntoa(offer_packet.siaddr)); | ||
764 | + printf("DHCPOFFER giaddr: %s\n", inet_ntoa(offer_packet.giaddr)); | ||
765 | } | ||
766 | |||
767 | - add_dhcp_offer(source.sin_addr,&offer_packet); | ||
768 | + add_dhcp_offer(source.sin_addr, &offer_packet); | ||
769 | |||
770 | valid_responses++; | ||
771 | - } | ||
772 | + } | ||
773 | |||
774 | - if (verbose) { | ||
775 | - printf(_("Total responses seen on the wire: %d\n"),responses); | ||
776 | - printf(_("Valid responses for this machine: %d\n"),valid_responses); | ||
777 | + if(verbose) { | ||
778 | + printf(_("Total responses seen on the wire: %d\n"), responses); | ||
779 | + printf(_("Valid responses for this machine: %d\n"), valid_responses); | ||
780 | } | ||
781 | |||
782 | return OK; | ||
783 | - } | ||
784 | - | ||
785 | +} | ||
786 | |||
787 | |||
788 | /* sends a DHCP packet */ | ||
789 | -int send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest){ | ||
790 | - struct sockaddr_in myname; | ||
791 | +int | ||
792 | +send_dhcp_packet(void *buffer, int buffer_size, int sock, struct sockaddr_in *dest) | ||
793 | +{ | ||
794 | int result; | ||
795 | |||
796 | - result=sendto(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)dest,sizeof(*dest)); | ||
797 | + result = sendto(sock, (char *)buffer, buffer_size, 0, (struct sockaddr *)dest, | ||
798 | + sizeof(*dest)); | ||
799 | |||
800 | - if (verbose) | ||
801 | - printf(_("send_dhcp_packet result: %d\n"),result); | ||
802 | + if(verbose) printf(_("send_dhcp_packet result: %d\n"), result); | ||
803 | |||
804 | - if(result<0) | ||
805 | - return ERROR; | ||
806 | + if(result < 0) return ERROR; | ||
807 | |||
808 | return OK; | ||
809 | - } | ||
810 | - | ||
811 | +} | ||
812 | |||
813 | |||
814 | /* receives a DHCP packet */ | ||
815 | -int receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, struct sockaddr_in *address){ | ||
816 | - struct timeval tv; | ||
817 | - fd_set readfds; | ||
818 | +int | ||
819 | +receive_dhcp_packet(void *buffer, int buffer_size, int sock, int timeout, | ||
820 | + struct sockaddr_in *address) | ||
821 | +{ | ||
822 | + struct timeval tv; | ||
823 | + fd_set readfds; | ||
824 | + fd_set oobfds; | ||
825 | int recv_result; | ||
826 | socklen_t address_size; | ||
827 | struct sockaddr_in source_address; | ||
828 | + int nfound; | ||
829 | |||
830 | + /* wait for data to arrive (up time timeout) */ | ||
831 | + tv.tv_sec = timeout; | ||
832 | + tv.tv_usec = 0; | ||
833 | + FD_ZERO(&readfds); | ||
834 | + FD_ZERO(&oobfds); | ||
835 | + FD_SET(sock, &readfds); | ||
836 | + FD_SET(sock, &oobfds); | ||
837 | + nfound = select(sock + 1, &readfds, NULL, &oobfds, &tv); | ||
838 | + | ||
839 | + /* make sure some data has arrived */ | ||
840 | + if(!FD_ISSET(sock, &readfds)) { | ||
841 | + if(verbose) | ||
842 | + printf(_("nfound: %d, No (more) data received\n"), nfound); | ||
843 | + return ERROR; | ||
844 | + } | ||
845 | |||
846 | - /* wait for data to arrive (up time timeout) */ | ||
847 | - tv.tv_sec=timeout; | ||
848 | - tv.tv_usec=0; | ||
849 | - FD_ZERO(&readfds); | ||
850 | - FD_SET(sock,&readfds); | ||
851 | - select(sock+1,&readfds,NULL,NULL,&tv); | ||
852 | - | ||
853 | - /* make sure some data has arrived */ | ||
854 | - if(!FD_ISSET(sock,&readfds)){ | ||
855 | - if (verbose) | ||
856 | - printf(_("No (more) data received\n")); | ||
857 | - return ERROR; | ||
858 | - } | ||
859 | - | ||
860 | - else{ | ||
861 | - | ||
862 | - /* 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 | ||
863 | - not being interpreted correctly. sigh... */ | ||
864 | - bzero(&source_address,sizeof(source_address)); | ||
865 | - address_size=sizeof(source_address); | ||
866 | - recv_result=recvfrom(sock,(char *)buffer,buffer_size,MSG_PEEK,(struct sockaddr *)&source_address,&address_size); | ||
867 | - if (verbose) | ||
868 | - printf("recv_result_1: %d\n",recv_result); | ||
869 | - recv_result=recvfrom(sock,(char *)buffer,buffer_size,0,(struct sockaddr *)&source_address,&address_size); | ||
870 | - if (verbose) | ||
871 | - printf("recv_result_2: %d\n",recv_result); | ||
872 | - | ||
873 | - if(recv_result==-1){ | ||
874 | - if (verbose) { | ||
875 | - printf(_("recvfrom() failed, ")); | ||
876 | - printf("errno: (%d) -> %s\n",errno,strerror(errno)); | ||
877 | - } | ||
878 | - return ERROR; | ||
879 | - } | ||
880 | - else{ | ||
881 | - if (verbose) { | ||
882 | - printf(_("receive_dhcp_packet() result: %d\n"),recv_result); | ||
883 | - printf(_("receive_dhcp_packet() source: %s\n"),inet_ntoa(source_address.sin_addr)); | ||
884 | - } | ||
885 | + /* why do we need to peek first? i don't know, its a hack. without it, | ||
886 | + * the source address of the first packet received was not being | ||
887 | + * interpreted correctly. sigh... */ | ||
888 | + memset(&source_address, 0, sizeof(source_address)); | ||
889 | + address_size = sizeof(source_address); | ||
890 | + recv_result = recvfrom(sock, (char *)buffer, buffer_size, MSG_PEEK, | ||
891 | + (struct sockaddr *)&source_address, &address_size); | ||
892 | + | ||
893 | + if(verbose) printf("recv_result_1: %d\n", recv_result); | ||
894 | + recv_result = recvfrom(sock, (char *)buffer, buffer_size, 0, | ||
895 | + (struct sockaddr *)&source_address, &address_size); | ||
896 | + | ||
897 | + if(verbose) printf("recv_result_2: %d\n", recv_result); | ||
898 | + | ||
899 | + if(recv_result == -1) { | ||
900 | + if(verbose) printf("errno: (%d) -> %s\n", errno, strerror(errno)); | ||
901 | + return ERROR; | ||
902 | + } | ||
903 | + | ||
904 | + if(verbose) { | ||
905 | + printf(_("receive_dhcp_packet() result: %d\n"), recv_result); | ||
906 | + printf(_("receive_dhcp_packet() source: %s\n"), | ||
907 | + inet_ntoa(source_address.sin_addr)); | ||
908 | + } | ||
909 | |||
910 | - memcpy(address,&source_address,sizeof(source_address)); | ||
911 | - return OK; | ||
912 | - } | ||
913 | - } | ||
914 | + memcpy(address, &source_address, sizeof(source_address)); | ||
915 | |||
916 | return OK; | ||
917 | - } | ||
918 | +} | ||
919 | |||
920 | |||
921 | /* creates a socket for DHCP communication */ | ||
922 | -int create_dhcp_socket(void){ | ||
923 | - struct sockaddr_in myname; | ||
924 | +int | ||
925 | +create_dhcp_socket(void) | ||
926 | +{ | ||
927 | + struct sockaddr_in myname; | ||
928 | struct ifreq interface; | ||
929 | - int sock; | ||
930 | - int flag=1; | ||
931 | + int sock; | ||
932 | + int flag = 1; | ||
933 | |||
934 | - /* Set up the address we're going to bind to. */ | ||
935 | - bzero(&myname,sizeof(myname)); | ||
936 | - myname.sin_family=AF_INET; | ||
937 | - myname.sin_port=htons(DHCP_CLIENT_PORT); | ||
938 | - myname.sin_addr.s_addr=INADDR_ANY; /* listen on any address */ | ||
939 | - bzero(&myname.sin_zero,sizeof(myname.sin_zero)); | ||
940 | - | ||
941 | - /* create a socket for DHCP communications */ | ||
942 | - sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); | ||
943 | - if(sock<0){ | ||
944 | + /* Set up the address we're going to bind to. */ | ||
945 | + memset(&myname, 0, sizeof(myname)); | ||
946 | + memset(&myname.sin_zero, 0, sizeof(myname.sin_zero)); | ||
947 | + myname.sin_family = AF_INET; | ||
948 | + /* listen to dhcp server port if we're in unicast mode */ | ||
949 | + myname.sin_port = htons(unicast_hops == 0 ? DHCP_CLIENT_PORT : DHCP_SERVER_PORT); | ||
950 | + myname.sin_addr.s_addr = unicast_hops == 0 ? INADDR_ANY : my_ip.s_addr; | ||
951 | + | ||
952 | + /* create a socket for DHCP communications */ | ||
953 | + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); | ||
954 | + if(sock < 0) { | ||
955 | printf(_("Error: Could not create socket!\n")); | ||
956 | exit(STATE_UNKNOWN); | ||
957 | - } | ||
958 | - | ||
959 | - if (verbose) | ||
960 | - printf("DHCP socket: %d\n",sock); | ||
961 | + } | ||
962 | |||
963 | - /* set the reuse address flag so we don't get errors when restarting */ | ||
964 | - flag=1; | ||
965 | - if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,(char *)&flag,sizeof(flag))<0){ | ||
966 | + /* set the reuse address flag so we don't get errors when restarting */ | ||
967 | + flag = 1; | ||
968 | + if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(flag)) < 0) { | ||
969 | printf(_("Error: Could not set reuse address option on DHCP socket!\n")); | ||
970 | exit(STATE_UNKNOWN); | ||
971 | - } | ||
972 | + } | ||
973 | |||
974 | - /* set the broadcast option - we need this to listen to DHCP broadcast messages */ | ||
975 | - if(setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char *)&flag,sizeof flag)<0){ | ||
976 | + /* set the broadcast option - we need this to listen to DHCP broadcast messages */ | ||
977 | + if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&flag, sizeof flag) < 0) { | ||
978 | printf(_("Error: Could not set broadcast option on DHCP socket!\n")); | ||
979 | exit(STATE_UNKNOWN); | ||
980 | - } | ||
981 | + } | ||
982 | |||
983 | /* bind socket to interface */ | ||
984 | #if defined(__linux__) | ||
985 | - strncpy(interface.ifr_ifrn.ifrn_name,network_interface_name,IFNAMSIZ); | ||
986 | - if(setsockopt(sock,SOL_SOCKET,SO_BINDTODEVICE,(char *)&interface,sizeof(interface))<0){ | ||
987 | - printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"),network_interface_name); | ||
988 | + strncpy(interface.ifr_ifrn.ifrn_name, network_interface_name, IFNAMSIZ); | ||
989 | + if(setsockopt | ||
990 | + (sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, | ||
991 | + sizeof(interface)) < 0) { | ||
992 | + printf(_("Error: Could not bind socket to interface %s. Check your privileges...\n"), | ||
993 | + network_interface_name); | ||
994 | exit(STATE_UNKNOWN); | ||
995 | - } | ||
996 | + } | ||
997 | |||
998 | #else | ||
999 | - strncpy(interface.ifr_name,network_interface_name,IFNAMSIZ); | ||
1000 | + strncpy(interface.ifr_name, network_interface_name, IFNAMSIZ); | ||
1001 | #endif | ||
1002 | |||
1003 | - /* bind the socket */ | ||
1004 | - if(bind(sock,(struct sockaddr *)&myname,sizeof(myname))<0){ | ||
1005 | - printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"),DHCP_CLIENT_PORT); | ||
1006 | + /* bind the socket */ | ||
1007 | + if(bind(sock, (struct sockaddr *)&myname, sizeof(myname)) < 0) { | ||
1008 | + printf(_("Error: Could not bind to DHCP socket (port %d)! Check your privileges...\n"), | ||
1009 | + DHCP_CLIENT_PORT); | ||
1010 | exit(STATE_UNKNOWN); | ||
1011 | - } | ||
1012 | - | ||
1013 | - return sock; | ||
1014 | - } | ||
1015 | - | ||
1016 | - | ||
1017 | -/* closes DHCP socket */ | ||
1018 | -int close_dhcp_socket(int sock){ | ||
1019 | - | ||
1020 | - close(sock); | ||
1021 | + } | ||
1022 | |||
1023 | - return OK; | ||
1024 | - } | ||
1025 | + return sock; | ||
1026 | +} | ||
1027 | |||
1028 | |||
1029 | /* adds a requested server address to list in memory */ | ||
1030 | -int add_requested_server(struct in_addr server_address){ | ||
1031 | +static int | ||
1032 | +add_requested_server(struct in_addr server_address) | ||
1033 | +{ | ||
1034 | requested_server *new_server; | ||
1035 | |||
1036 | - new_server=(requested_server *)malloc(sizeof(requested_server)); | ||
1037 | - if(new_server==NULL) | ||
1038 | + new_server = (requested_server *) malloc(sizeof(requested_server)); | ||
1039 | + if(new_server == NULL) | ||
1040 | return ERROR; | ||
1041 | |||
1042 | - new_server->server_address=server_address; | ||
1043 | + new_server->server_address = server_address; | ||
1044 | |||
1045 | - new_server->next=requested_server_list; | ||
1046 | - requested_server_list=new_server; | ||
1047 | + new_server->next = requested_server_list; | ||
1048 | + requested_server_list = new_server; | ||
1049 | |||
1050 | requested_servers++; | ||
1051 | |||
1052 | - if (verbose) | ||
1053 | - printf(_("Requested server address: %s\n"),inet_ntoa(new_server->server_address)); | ||
1054 | + if(verbose) | ||
1055 | + printf(_("Requested server address: %s\n"), | ||
1056 | + inet_ntoa(new_server->server_address)); | ||
1057 | |||
1058 | return OK; | ||
1059 | - } | ||
1060 | +} | ||
1061 | |||
1062 | |||
1063 | |||
1064 | |||
1065 | /* adds a DHCP OFFER to list in memory */ | ||
1066 | -int add_dhcp_offer(struct in_addr source,dhcp_packet *offer_packet){ | ||
1067 | +int | ||
1068 | +add_dhcp_offer(struct in_addr source, dhcp_packet * offer_packet) | ||
1069 | +{ | ||
1070 | dhcp_offer *new_offer; | ||
1071 | int x; | ||
1072 | int y; | ||
1073 | unsigned option_type; | ||
1074 | unsigned option_length; | ||
1075 | |||
1076 | - if(offer_packet==NULL) | ||
1077 | - return ERROR; | ||
1078 | + if(offer_packet == NULL) return ERROR; | ||
1079 | |||
1080 | /* process all DHCP options present in the packet */ | ||
1081 | - for(x=4;x<MAX_DHCP_OPTIONS_LENGTH;){ | ||
1082 | + for(x = 4; x < MAX_DHCP_OPTIONS_LENGTH;) { | ||
1083 | |||
1084 | /* end of options (0 is really just a pad, but bail out anyway) */ | ||
1085 | - if((int)offer_packet->options[x]==-1 || (int)offer_packet->options[x]==0) | ||
1086 | + if((int)offer_packet->options[x] == -1 || (int)offer_packet->options[x] == 0) | ||
1087 | break; | ||
1088 | |||
1089 | /* get option type */ | ||
1090 | - option_type=offer_packet->options[x++]; | ||
1091 | + option_type = offer_packet->options[x++]; | ||
1092 | |||
1093 | /* get option length */ | ||
1094 | - option_length=offer_packet->options[x++]; | ||
1095 | + option_length = offer_packet->options[x++]; | ||
1096 | |||
1097 | - if (verbose) | ||
1098 | - printf("Option: %d (0x%02X)\n",option_type,option_length); | ||
1099 | + if(verbose) | ||
1100 | + printf("Option: %d (0x%02X)\n", option_type, option_length); | ||
1101 | |||
1102 | /* get option data */ | ||
1103 | - if(option_type==DHCP_OPTION_LEASE_TIME) { | ||
1104 | - memcpy(&dhcp_lease_time, &offer_packet->options[x], | ||
1105 | - sizeof(dhcp_lease_time)); | ||
1106 | - dhcp_lease_time = ntohl(dhcp_lease_time); | ||
1107 | - } | ||
1108 | - if(option_type==DHCP_OPTION_RENEWAL_TIME) { | ||
1109 | - memcpy(&dhcp_renewal_time, &offer_packet->options[x], | ||
1110 | - sizeof(dhcp_renewal_time)); | ||
1111 | - dhcp_renewal_time = ntohl(dhcp_renewal_time); | ||
1112 | - } | ||
1113 | - if(option_type==DHCP_OPTION_REBINDING_TIME) { | ||
1114 | - memcpy(&dhcp_rebinding_time, &offer_packet->options[x], | ||
1115 | - sizeof(dhcp_rebinding_time)); | ||
1116 | - dhcp_rebinding_time = ntohl(dhcp_rebinding_time); | ||
1117 | - } | ||
1118 | + if(option_type == DHCP_OPTION_LEASE_TIME) { | ||
1119 | + memcpy(&dhcp_lease_time, &offer_packet->options[x], | ||
1120 | + sizeof(dhcp_lease_time)); | ||
1121 | + dhcp_lease_time = ntohl(dhcp_lease_time); | ||
1122 | + } | ||
1123 | + if(option_type == DHCP_OPTION_RENEWAL_TIME) { | ||
1124 | + memcpy(&dhcp_renewal_time, &offer_packet->options[x], | ||
1125 | + sizeof(dhcp_renewal_time)); | ||
1126 | + dhcp_renewal_time = ntohl(dhcp_renewal_time); | ||
1127 | + } | ||
1128 | + if(option_type == DHCP_OPTION_REBINDING_TIME) { | ||
1129 | + memcpy(&dhcp_rebinding_time, &offer_packet->options[x], | ||
1130 | + sizeof(dhcp_rebinding_time)); | ||
1131 | + dhcp_rebinding_time = ntohl(dhcp_rebinding_time); | ||
1132 | + } | ||
1133 | |||
1134 | /* skip option data we're ignoring */ | ||
1135 | - else | ||
1136 | - for(y=0;y<option_length;y++,x++); | ||
1137 | - } | ||
1138 | + else for(y = 0; y < option_length; y++, x++) ; | ||
1139 | + } | ||
1140 | |||
1141 | - if (verbose) { | ||
1142 | - if(dhcp_lease_time==DHCP_INFINITE_TIME) | ||
1143 | + if(verbose) { | ||
1144 | + if(dhcp_lease_time == DHCP_INFINITE_TIME) | ||
1145 | printf(_("Lease Time: Infinite\n")); | ||
1146 | else | ||
1147 | - printf(_("Lease Time: %lu seconds\n"),(unsigned long)dhcp_lease_time); | ||
1148 | - if(dhcp_renewal_time==DHCP_INFINITE_TIME) | ||
1149 | + printf(_("Lease Time: %lu seconds\n"), (unsigned long)dhcp_lease_time); | ||
1150 | + if(dhcp_renewal_time == DHCP_INFINITE_TIME) | ||
1151 | printf(_("Renewal Time: Infinite\n")); | ||
1152 | else | ||
1153 | - printf(_("Renewal Time: %lu seconds\n"),(unsigned long)dhcp_renewal_time); | ||
1154 | - if(dhcp_rebinding_time==DHCP_INFINITE_TIME) | ||
1155 | + printf(_("Renewal Time: %lu seconds\n"), | ||
1156 | + (unsigned long)dhcp_renewal_time); | ||
1157 | + if(dhcp_rebinding_time == DHCP_INFINITE_TIME) | ||
1158 | printf(_("Rebinding Time: Infinite\n")); | ||
1159 | - printf(_("Rebinding Time: %lu seconds\n"),(unsigned long)dhcp_rebinding_time); | ||
1160 | + printf(_("Rebinding Time: %lu seconds\n"), | ||
1161 | + (unsigned long)dhcp_rebinding_time); | ||
1162 | } | ||
1163 | |||
1164 | - new_offer=(dhcp_offer *)malloc(sizeof(dhcp_offer)); | ||
1165 | + new_offer = (dhcp_offer *) malloc(sizeof(dhcp_offer)); | ||
1166 | |||
1167 | - if(new_offer==NULL) | ||
1168 | - return ERROR; | ||
1169 | + if(new_offer == NULL) return ERROR; | ||
1170 | |||
1171 | - new_offer->server_address=source; | ||
1172 | - new_offer->offered_address=offer_packet->yiaddr; | ||
1173 | - new_offer->lease_time=dhcp_lease_time; | ||
1174 | - new_offer->renewal_time=dhcp_renewal_time; | ||
1175 | - new_offer->rebinding_time=dhcp_rebinding_time; | ||
1176 | + new_offer->server_address = source; | ||
1177 | + new_offer->offered_address = offer_packet->yiaddr; | ||
1178 | + new_offer->lease_time = dhcp_lease_time; | ||
1179 | + new_offer->renewal_time = dhcp_renewal_time; | ||
1180 | + new_offer->rebinding_time = dhcp_rebinding_time; | ||
1181 | |||
1182 | |||
1183 | - if (verbose) { | ||
1184 | - printf(_("Added offer from server @ %s"),inet_ntoa(new_offer->server_address)); | ||
1185 | - printf(_(" of IP address %s\n"),inet_ntoa(new_offer->offered_address)); | ||
1186 | + if(verbose) { | ||
1187 | + printf(_("Added offer from server @ %s"), | ||
1188 | + inet_ntoa(new_offer->server_address)); | ||
1189 | + printf(_(" of IP address %s\n"), inet_ntoa(new_offer->offered_address)); | ||
1190 | } | ||
1191 | |||
1192 | /* add new offer to head of list */ | ||
1193 | - new_offer->next=dhcp_offer_list; | ||
1194 | - dhcp_offer_list=new_offer; | ||
1195 | + new_offer->next = dhcp_offer_list; | ||
1196 | + dhcp_offer_list = new_offer; | ||
1197 | |||
1198 | return OK; | ||
1199 | - } | ||
1200 | +} | ||
1201 | |||
1202 | |||
1203 | /* frees memory allocated to DHCP OFFER list */ | ||
1204 | -int free_dhcp_offer_list(void){ | ||
1205 | +int | ||
1206 | +free_dhcp_offer_list(void) | ||
1207 | +{ | ||
1208 | dhcp_offer *this_offer; | ||
1209 | dhcp_offer *next_offer; | ||
1210 | |||
1211 | - for(this_offer=dhcp_offer_list;this_offer!=NULL;this_offer=next_offer){ | ||
1212 | - next_offer=this_offer->next; | ||
1213 | + for(this_offer = dhcp_offer_list; this_offer != NULL; this_offer = next_offer) { | ||
1214 | + next_offer = this_offer->next; | ||
1215 | free(this_offer); | ||
1216 | - } | ||
1217 | + } | ||
1218 | |||
1219 | return OK; | ||
1220 | - } | ||
1221 | +} | ||
1222 | |||
1223 | |||
1224 | /* frees memory allocated to requested server list */ | ||
1225 | -int free_requested_server_list(void){ | ||
1226 | +int | ||
1227 | +free_requested_server_list(void) | ||
1228 | +{ | ||
1229 | requested_server *this_server; | ||
1230 | requested_server *next_server; | ||
1231 | |||
1232 | - for(this_server=requested_server_list;this_server!=NULL;this_server=next_server){ | ||
1233 | - next_server=this_server->next; | ||
1234 | + for(this_server = requested_server_list; this_server != NULL; | ||
1235 | + this_server = next_server) { | ||
1236 | + next_server = this_server->next; | ||
1237 | free(this_server); | ||
1238 | - } | ||
1239 | - | ||
1240 | + } | ||
1241 | + | ||
1242 | return OK; | ||
1243 | - } | ||
1244 | +} | ||
1245 | |||
1246 | |||
1247 | /* gets state and plugin output to return */ | ||
1248 | -int get_results(void){ | ||
1249 | +int | ||
1250 | +get_results(void) | ||
1251 | +{ | ||
1252 | dhcp_offer *temp_offer; | ||
1253 | requested_server *temp_server; | ||
1254 | int result; | ||
1255 | - u_int32_t max_lease_time=0; | ||
1256 | + u_int32_t max_lease_time = 0; | ||
1257 | |||
1258 | - received_requested_address=FALSE; | ||
1259 | + received_requested_address = FALSE; | ||
1260 | |||
1261 | /* checks responses from requested servers */ | ||
1262 | - requested_responses=0; | ||
1263 | - if(requested_servers>0){ | ||
1264 | + requested_responses = 0; | ||
1265 | + if(requested_servers > 0) { | ||
1266 | |||
1267 | - for(temp_server=requested_server_list;temp_server!=NULL;temp_server=temp_server->next){ | ||
1268 | + for(temp_server = requested_server_list; temp_server != NULL; | ||
1269 | + temp_server = temp_server->next) { | ||
1270 | |||
1271 | - for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ | ||
1272 | + for(temp_offer = dhcp_offer_list; temp_offer != NULL; | ||
1273 | + temp_offer = temp_offer->next) { | ||
1274 | |||
1275 | /* get max lease time we were offered */ | ||
1276 | - if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) | ||
1277 | - max_lease_time=temp_offer->lease_time; | ||
1278 | - | ||
1279 | + if(temp_offer->lease_time > max_lease_time | ||
1280 | + || temp_offer->lease_time == DHCP_INFINITE_TIME) | ||
1281 | + max_lease_time = temp_offer->lease_time; | ||
1282 | + | ||
1283 | /* see if we got the address we requested */ | ||
1284 | - if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) | ||
1285 | - received_requested_address=TRUE; | ||
1286 | + if(!memcmp(&requested_address, &temp_offer->offered_address, | ||
1287 | + sizeof(requested_address))) | ||
1288 | + received_requested_address = TRUE; | ||
1289 | |||
1290 | /* see if the servers we wanted a response from talked to us or not */ | ||
1291 | - if(!memcmp(&temp_offer->server_address,&temp_server->server_address,sizeof(temp_server->server_address))){ | ||
1292 | - if (verbose) { | ||
1293 | - printf(_("DHCP Server Match: Offerer=%s"),inet_ntoa(temp_offer->server_address)); | ||
1294 | - printf(_(" Requested=%s\n"),inet_ntoa(temp_server->server_address)); | ||
1295 | - } | ||
1296 | + if(!memcmp(&temp_offer->server_address, &temp_server->server_address, | ||
1297 | + sizeof(temp_server->server_address))) | ||
1298 | + { | ||
1299 | + if(verbose) { | ||
1300 | + printf(_("DHCP Server Match: Offerer=%s"), | ||
1301 | + inet_ntoa(temp_offer->server_address)); | ||
1302 | + printf(_(" Requested=%s\n"), | ||
1303 | + inet_ntoa(temp_server->server_address)); | ||
1304 | + } | ||
1305 | requested_responses++; | ||
1306 | - } | ||
1307 | - } | ||
1308 | - } | ||
1309 | - | ||
1310 | - } | ||
1311 | + } | ||
1312 | + } | ||
1313 | + } | ||
1314 | + } | ||
1315 | |||
1316 | /* else check and see if we got our requested address from any server */ | ||
1317 | - else{ | ||
1318 | - | ||
1319 | - for(temp_offer=dhcp_offer_list;temp_offer!=NULL;temp_offer=temp_offer->next){ | ||
1320 | - | ||
1321 | + else { | ||
1322 | + for(temp_offer = dhcp_offer_list; temp_offer != NULL; | ||
1323 | + temp_offer = temp_offer->next) | ||
1324 | + { | ||
1325 | /* get max lease time we were offered */ | ||
1326 | - if(temp_offer->lease_time>max_lease_time || temp_offer->lease_time==DHCP_INFINITE_TIME) | ||
1327 | - max_lease_time=temp_offer->lease_time; | ||
1328 | - | ||
1329 | + if(temp_offer->lease_time > max_lease_time | ||
1330 | + || temp_offer->lease_time == DHCP_INFINITE_TIME) | ||
1331 | + max_lease_time = temp_offer->lease_time; | ||
1332 | + | ||
1333 | /* see if we got the address we requested */ | ||
1334 | - if(!memcmp(&requested_address,&temp_offer->offered_address,sizeof(requested_address))) | ||
1335 | - received_requested_address=TRUE; | ||
1336 | - } | ||
1337 | - } | ||
1338 | - | ||
1339 | - result=STATE_OK; | ||
1340 | - if(valid_responses==0) | ||
1341 | - result=STATE_CRITICAL; | ||
1342 | - else if(requested_servers>0 && requested_responses==0) | ||
1343 | - result=STATE_CRITICAL; | ||
1344 | - else if(requested_responses<requested_servers) | ||
1345 | - result=STATE_WARNING; | ||
1346 | - else if(request_specific_address==TRUE && received_requested_address==FALSE) | ||
1347 | - result=STATE_WARNING; | ||
1348 | + if(!memcmp(&requested_address, &temp_offer->offered_address, | ||
1349 | + sizeof(requested_address))) | ||
1350 | + received_requested_address = TRUE; | ||
1351 | + } | ||
1352 | + } | ||
1353 | |||
1354 | + result = STATE_OK; | ||
1355 | + if(valid_responses == 0) | ||
1356 | + result = STATE_CRITICAL; | ||
1357 | + else if(requested_servers > 0 && requested_responses == 0) | ||
1358 | + result = STATE_CRITICAL; | ||
1359 | + else if(requested_responses < requested_servers) | ||
1360 | + result = STATE_WARNING; | ||
1361 | + else if(request_specific_address == TRUE && received_requested_address == FALSE) | ||
1362 | + result = STATE_WARNING; | ||
1363 | |||
1364 | - printf("DHCP %s: ",(result==STATE_OK)?"ok":"problem"); | ||
1365 | + printf("DHCP %s: ", (result == STATE_OK) ? "ok" : "problem"); | ||
1366 | |||
1367 | /* we didn't receive any DHCPOFFERs */ | ||
1368 | - if(dhcp_offer_list==NULL){ | ||
1369 | + if(dhcp_offer_list == NULL) { | ||
1370 | printf(_("No DHCPOFFERs were received.\n")); | ||
1371 | return result; | ||
1372 | - } | ||
1373 | - | ||
1374 | - printf(_("Received %d DHCPOFFER(s)"),valid_responses); | ||
1375 | + } | ||
1376 | |||
1377 | - if(requested_servers>0) | ||
1378 | - printf(_(", %s%d of %d requested servers responded"),((requested_responses<requested_servers) && requested_responses>0)?"only ":"",requested_responses,requested_servers); | ||
1379 | + printf(_("Received %d DHCPOFFER(s)"), valid_responses); | ||
1380 | |||
1381 | - if(request_specific_address==TRUE) | ||
1382 | - printf(_(", requested address (%s) was %soffered"),inet_ntoa(requested_address),(received_requested_address==TRUE)?"":_("not ")); | ||
1383 | + if(requested_servers > 0) | ||
1384 | + printf(_(", %s%d of %d requested servers responded"), | ||
1385 | + ((requested_responses < requested_servers) | ||
1386 | + && requested_responses > 0) ? "only " : "", | ||
1387 | + requested_responses, | ||
1388 | + requested_servers); | ||
1389 | + | ||
1390 | + if(request_specific_address == TRUE) | ||
1391 | + printf(_(", requested address (%s) was %soffered"), | ||
1392 | + inet_ntoa(requested_address), | ||
1393 | + (received_requested_address == TRUE) ? "" : _("not ")); | ||
1394 | |||
1395 | printf(_(", max lease time = ")); | ||
1396 | - if(max_lease_time==DHCP_INFINITE_TIME) | ||
1397 | + if(max_lease_time == DHCP_INFINITE_TIME) | ||
1398 | printf(_("Infinity")); | ||
1399 | else | ||
1400 | - printf("%lu sec",(unsigned long)max_lease_time); | ||
1401 | + printf("%lu sec", (unsigned long)max_lease_time); | ||
1402 | |||
1403 | - printf(".\n"); | ||
1404 | + puts("."); | ||
1405 | |||
1406 | return result; | ||
1407 | - } | ||
1408 | +} | ||
1409 | |||
1410 | |||
1411 | /* process command-line arguments */ | ||
1412 | -int process_arguments(int argc, char **argv){ | ||
1413 | - int c; | ||
1414 | - | ||
1415 | - if(argc<1) | ||
1416 | - return ERROR; | ||
1417 | - | ||
1418 | - c=0; | ||
1419 | - while((c+=(call_getopt(argc-c,&argv[c])))<argc){ | ||
1420 | - | ||
1421 | - /* | ||
1422 | - if(is_option(argv[c])) | ||
1423 | - continue; | ||
1424 | - */ | ||
1425 | - } | ||
1426 | - | ||
1427 | - return validate_arguments(); | ||
1428 | - } | ||
1429 | - | ||
1430 | - | ||
1431 | - | ||
1432 | -int call_getopt(int argc, char **argv){ | ||
1433 | - int c=0; | ||
1434 | - int i=0; | ||
1435 | +int | ||
1436 | +process_arguments(int argc, char **argv) | ||
1437 | +{ | ||
1438 | + int c = 0; | ||
1439 | struct in_addr ipaddress; | ||
1440 | - | ||
1441 | -#ifdef HAVE_GETOPT_H | ||
1442 | int option_index = 0; | ||
1443 | - static struct option long_options[] = | ||
1444 | - { | ||
1445 | - {"serverip", required_argument,0,'s'}, | ||
1446 | - {"requestedip", required_argument,0,'r'}, | ||
1447 | - {"timeout", required_argument,0,'t'}, | ||
1448 | - {"interface", required_argument,0,'i'}, | ||
1449 | - {"verbose", no_argument, 0,'v'}, | ||
1450 | - {"version", no_argument, 0,'V'}, | ||
1451 | - {"help", no_argument, 0,'h'}, | ||
1452 | - {0,0,0,0} | ||
1453 | - }; | ||
1454 | -#endif | ||
1455 | |||
1456 | - while(1){ | ||
1457 | -#ifdef HAVE_GETOPT_H | ||
1458 | - c=getopt_long(argc,argv,"+hVvt:s:r:t:i:",long_options,&option_index); | ||
1459 | -#else | ||
1460 | - c=getopt(argc,argv,"+?hVvt:s:r:t:i:"); | ||
1461 | -#endif | ||
1462 | + static struct option long_options[] = { | ||
1463 | + {"host", required_argument, 0, 'H'}, | ||
1464 | + {"serverip", required_argument, 0, 's'}, | ||
1465 | + {"requestedip", required_argument, 0, 'r'}, | ||
1466 | + {"timeout", required_argument, 0, 't'}, | ||
1467 | + {"interface", required_argument, 0, 'i'}, | ||
1468 | + {"unicast", required_argument, 0, 'u'}, | ||
1469 | + {"verbose", no_argument, 0, 'v'}, | ||
1470 | + {"version", no_argument, 0, 'V'}, | ||
1471 | + {"help", no_argument, 0, 'h'}, | ||
1472 | + {0, 0, 0, 0} | ||
1473 | + }; | ||
1474 | |||
1475 | - i++; | ||
1476 | + while(1) { | ||
1477 | + c = getopt_long(argc, argv, "+hVvt:s:r:t:i:u:", long_options, &option_index); | ||
1478 | |||
1479 | - if(c==-1||c==EOF||c==1) | ||
1480 | + if(c == -1 || c == EOF || c == 1) | ||
1481 | break; | ||
1482 | |||
1483 | - switch(c){ | ||
1484 | - case 'w': | ||
1485 | - case 'r': | ||
1486 | - case 't': | ||
1487 | - case 'i': | ||
1488 | - i++; | ||
1489 | + switch (c) { | ||
1490 | + case 'u': | ||
1491 | + unicast_hops = (u_int8_t)strtoul(optarg, NULL, 0); | ||
1492 | break; | ||
1493 | - default: | ||
1494 | - break; | ||
1495 | - } | ||
1496 | - | ||
1497 | - switch(c){ | ||
1498 | - | ||
1499 | - case 's': /* DHCP server address */ | ||
1500 | - if(inet_aton(optarg,&ipaddress)) | ||
1501 | + case 's': case 'H': /* DHCP server address */ | ||
1502 | + if(inet_aton(optarg, &ipaddress)) | ||
1503 | add_requested_server(ipaddress); | ||
1504 | /* | ||
1505 | - else | ||
1506 | - usage("Invalid server IP address\n"); | ||
1507 | - */ | ||
1508 | + else | ||
1509 | + usage("Invalid server IP address\n"); | ||
1510 | + */ | ||
1511 | + inet_aton(optarg, &dhcp_ip); | ||
1512 | + if(verbose) | ||
1513 | + printf("querying %s\n", inet_ntoa(dhcp_ip)); | ||
1514 | break; | ||
1515 | |||
1516 | - case 'r': /* address we are requested from DHCP servers */ | ||
1517 | - if(inet_aton(optarg,&ipaddress)){ | ||
1518 | - requested_address=ipaddress; | ||
1519 | - request_specific_address=TRUE; | ||
1520 | - } | ||
1521 | + case 'r': /* address we are requested from DHCP servers */ | ||
1522 | + if(inet_aton(optarg, &ipaddress)) { | ||
1523 | + requested_address = ipaddress; | ||
1524 | + request_specific_address = TRUE; | ||
1525 | + } | ||
1526 | /* | ||
1527 | - else | ||
1528 | - usage("Invalid requested IP address\n"); | ||
1529 | - */ | ||
1530 | + else | ||
1531 | + usage("Invalid requested IP address\n"); | ||
1532 | + */ | ||
1533 | break; | ||
1534 | |||
1535 | - case 't': /* timeout */ | ||
1536 | - | ||
1537 | + case 't': /* timeout */ | ||
1538 | /* | ||
1539 | - if(is_intnonneg(optarg)) | ||
1540 | - */ | ||
1541 | - if(atoi(optarg)>0) | ||
1542 | - dhcpoffer_timeout=atoi(optarg); | ||
1543 | + if(is_intnonneg(optarg)) | ||
1544 | + */ | ||
1545 | + if(atoi(optarg) > 0) | ||
1546 | + dhcpoffer_timeout = atoi(optarg); | ||
1547 | /* | ||
1548 | - else | ||
1549 | - usage("Time interval must be a nonnegative integer\n"); | ||
1550 | - */ | ||
1551 | + else | ||
1552 | + usage("Time interval must be a nonnegative integer\n"); | ||
1553 | + */ | ||
1554 | break; | ||
1555 | |||
1556 | - case 'i': /* interface name */ | ||
1557 | - | ||
1558 | - strncpy(network_interface_name,optarg,sizeof(network_interface_name)-1); | ||
1559 | - network_interface_name[sizeof(network_interface_name)-1]='\x0'; | ||
1560 | - | ||
1561 | + case 'i': /* interface name */ | ||
1562 | + strncpy(network_interface_name, optarg, | ||
1563 | + sizeof(network_interface_name) - 1); | ||
1564 | + network_interface_name[sizeof(network_interface_name) - 1] = '\x0'; | ||
1565 | break; | ||
1566 | |||
1567 | - case 'V': /* version */ | ||
1568 | - print_revision(progname,revision); | ||
1569 | + case 'V': /* version */ | ||
1570 | + print_revision(progname, revision); | ||
1571 | exit(STATE_OK); | ||
1572 | |||
1573 | - case 'h': /* help */ | ||
1574 | + case 'h': /* help */ | ||
1575 | print_help(); | ||
1576 | exit(STATE_OK); | ||
1577 | |||
1578 | - case 'v': /* verbose */ | ||
1579 | - verbose=1; | ||
1580 | + case 'v': /* verbose */ | ||
1581 | + verbose++; | ||
1582 | break; | ||
1583 | |||
1584 | - case '?': /* help */ | ||
1585 | - usage2 (_("Unknown argument"), optarg); | ||
1586 | + case '?': /* help */ | ||
1587 | + usage2(_("Unknown argument"), optarg); | ||
1588 | break; | ||
1589 | |||
1590 | default: | ||
1591 | break; | ||
1592 | - } | ||
1593 | - } | ||
1594 | - | ||
1595 | - return i; | ||
1596 | - } | ||
1597 | + } | ||
1598 | + } | ||
1599 | + | ||
1600 | + return validate_arguments(); | ||
1601 | +} | ||
1602 | |||
1603 | |||
1604 | -int validate_arguments(void){ | ||
1605 | +int | ||
1606 | +validate_arguments(void) | ||
1607 | +{ | ||
1608 | |||
1609 | return OK; | ||
1610 | - } | ||
1611 | +} | ||
1612 | |||
1613 | #if defined(__sun__) || defined(__solaris__) || defined(__hpux__) | ||
1614 | |||
1615 | - /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ | ||
1616 | + /* Kompf 2000-2003 see ACKNOWLEDGEMENTS */ | ||
1617 | |||
1618 | /* get a message from a stream; return type of message */ | ||
1619 | -static int get_msg(int fd) | ||
1620 | +static int | ||
1621 | +get_msg(int fd) | ||
1622 | { | ||
1623 | - int flags = 0; | ||
1624 | - int res, ret; | ||
1625 | - ctl_area[0] = 0; | ||
1626 | - dat_area[0] = 0; | ||
1627 | - ret = 0; | ||
1628 | - res = getmsg(fd, &ctl, &dat, &flags); | ||
1629 | - | ||
1630 | - if(res < 0) { | ||
1631 | - if(errno == EINTR) { | ||
1632 | - return(GOT_INTR); | ||
1633 | - } else { | ||
1634 | - printf("%s\n", "get_msg FAILED."); | ||
1635 | - return(GOT_ERR); | ||
1636 | - } | ||
1637 | - } | ||
1638 | - if(ctl.len > 0) { | ||
1639 | - ret |= GOT_CTRL; | ||
1640 | - } | ||
1641 | - if(dat.len > 0) { | ||
1642 | - ret |= GOT_DATA; | ||
1643 | - } | ||
1644 | - return(ret); | ||
1645 | + int flags = 0; | ||
1646 | + int res, ret; | ||
1647 | + | ||
1648 | + ctl_area[0] = 0; | ||
1649 | + dat_area[0] = 0; | ||
1650 | + ret = 0; | ||
1651 | + res = getmsg(fd, &ctl, &dat, &flags); | ||
1652 | + | ||
1653 | + if(res < 0) { | ||
1654 | + if(errno == EINTR) { | ||
1655 | + return (GOT_INTR); | ||
1656 | + } | ||
1657 | + else { | ||
1658 | + printf("%s\n", "get_msg FAILED."); | ||
1659 | + return (GOT_ERR); | ||
1660 | + } | ||
1661 | + } | ||
1662 | + if(ctl.len > 0) { | ||
1663 | + ret |= GOT_CTRL; | ||
1664 | + } | ||
1665 | + if(dat.len > 0) { | ||
1666 | + ret |= GOT_DATA; | ||
1667 | + } | ||
1668 | + return (ret); | ||
1669 | } | ||
1670 | |||
1671 | /* verify that dl_primitive in ctl_area = prim */ | ||
1672 | -static int check_ctrl(int prim) | ||
1673 | +static int | ||
1674 | +check_ctrl(int prim) | ||
1675 | { | ||
1676 | - dl_error_ack_t *err_ack = (dl_error_ack_t *)ctl_area; | ||
1677 | - if(err_ack->dl_primitive != prim) { | ||
1678 | - printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), strerror(errno)); | ||
1679 | - exit(STATE_UNKNOWN); | ||
1680 | - } | ||
1681 | - return 0; | ||
1682 | + dl_error_ack_t *err_ack = (dl_error_ack_t *) ctl_area; | ||
1683 | + | ||
1684 | + if(err_ack->dl_primitive != prim) { | ||
1685 | + printf(_("Error: DLPI stream API failed to get MAC in check_ctrl: %s.\n"), | ||
1686 | + strerror(errno)); | ||
1687 | + exit(STATE_UNKNOWN); | ||
1688 | + } | ||
1689 | + return 0; | ||
1690 | } | ||
1691 | |||
1692 | /* put a control message on a stream */ | ||
1693 | -static int put_ctrl(int fd, int len, int pri) | ||
1694 | +static int | ||
1695 | +put_ctrl(int fd, int len, int pri) | ||
1696 | { | ||
1697 | - ctl.len = len; | ||
1698 | - if(putmsg(fd, &ctl, 0, pri) < 0) { | ||
1699 | - printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), strerror(errno)); | ||
1700 | - exit(STATE_UNKNOWN); | ||
1701 | - } | ||
1702 | - return 0; | ||
1703 | + ctl.len = len; | ||
1704 | + if(putmsg(fd, &ctl, 0, pri) < 0) { | ||
1705 | + printf(_("Error: DLPI stream API failed to get MAC in put_ctrl/putmsg(): %s.\n"), | ||
1706 | + strerror(errno)); | ||
1707 | + exit(STATE_UNKNOWN); | ||
1708 | + } | ||
1709 | + | ||
1710 | + return 0; | ||
1711 | } | ||
1712 | |||
1713 | + | ||
1714 | /* put a control + data message on a stream */ | ||
1715 | -static int put_both(int fd, int clen, int dlen, int pri) | ||
1716 | +static int | ||
1717 | +put_both(int fd, int clen, int dlen, int pri) | ||
1718 | { | ||
1719 | - ctl.len = clen; | ||
1720 | - dat.len = dlen; | ||
1721 | - if(putmsg(fd, &ctl, &dat, pri) < 0) { | ||
1722 | - printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), strerror(errno)); | ||
1723 | - exit(STATE_UNKNOWN); | ||
1724 | - } | ||
1725 | - return 0; | ||
1726 | + ctl.len = clen; | ||
1727 | + dat.len = dlen; | ||
1728 | + if(putmsg(fd, &ctl, &dat, pri) < 0) { | ||
1729 | + printf(_("Error: DLPI stream API failed to get MAC in put_both/putmsg().\n"), | ||
1730 | + strerror(errno)); | ||
1731 | + exit(STATE_UNKNOWN); | ||
1732 | + } | ||
1733 | + | ||
1734 | + return 0; | ||
1735 | } | ||
1736 | |||
1737 | + | ||
1738 | /* open file descriptor and attach */ | ||
1739 | -static int dl_open(const char *dev, int unit, int *fd) | ||
1740 | +static int | ||
1741 | +dl_open(const char *dev, int unit, int *fd) | ||
1742 | { | ||
1743 | - dl_attach_req_t *attach_req = (dl_attach_req_t *)ctl_area; | ||
1744 | - if((*fd = open(dev, O_RDWR)) == -1) { | ||
1745 | - printf(_("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), dev, strerror(errno)); | ||
1746 | - exit(STATE_UNKNOWN); | ||
1747 | - } | ||
1748 | - attach_req->dl_primitive = DL_ATTACH_REQ; | ||
1749 | - attach_req->dl_ppa = unit; | ||
1750 | - put_ctrl(*fd, sizeof(dl_attach_req_t), 0); | ||
1751 | - get_msg(*fd); | ||
1752 | - return check_ctrl(DL_OK_ACK); | ||
1753 | + dl_attach_req_t *attach_req = (dl_attach_req_t *) ctl_area; | ||
1754 | + | ||
1755 | + if((*fd = open(dev, O_RDWR)) == -1) { | ||
1756 | + printf(_ | ||
1757 | + ("Error: DLPI stream API failed to get MAC in dl_attach_req/open(%s..): %s.\n"), | ||
1758 | + dev, strerror(errno)); | ||
1759 | + exit(STATE_UNKNOWN); | ||
1760 | + } | ||
1761 | + attach_req->dl_primitive = DL_ATTACH_REQ; | ||
1762 | + attach_req->dl_ppa = unit; | ||
1763 | + put_ctrl(*fd, sizeof(dl_attach_req_t), 0); | ||
1764 | + get_msg(*fd); | ||
1765 | + return check_ctrl(DL_OK_ACK); | ||
1766 | } | ||
1767 | |||
1768 | + | ||
1769 | /* send DL_BIND_REQ */ | ||
1770 | -static int dl_bind(int fd, int sap, u_char *addr) | ||
1771 | +static int | ||
1772 | +dl_bind(int fd, int sap, u_char * addr) | ||
1773 | { | ||
1774 | - dl_bind_req_t *bind_req = (dl_bind_req_t *)ctl_area; | ||
1775 | - dl_bind_ack_t *bind_ack = (dl_bind_ack_t *)ctl_area; | ||
1776 | - bind_req->dl_primitive = DL_BIND_REQ; | ||
1777 | - bind_req->dl_sap = sap; | ||
1778 | - bind_req->dl_max_conind = 1; | ||
1779 | - bind_req->dl_service_mode = DL_CLDLS; | ||
1780 | - bind_req->dl_conn_mgmt = 0; | ||
1781 | - bind_req->dl_xidtest_flg = 0; | ||
1782 | - put_ctrl(fd, sizeof(dl_bind_req_t), 0); | ||
1783 | - get_msg(fd); | ||
1784 | - if (GOT_ERR == check_ctrl(DL_BIND_ACK)) { | ||
1785 | - printf(_("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), strerror(errno)); | ||
1786 | - exit(STATE_UNKNOWN); | ||
1787 | - } | ||
1788 | - bcopy((u_char *)bind_ack + bind_ack->dl_addr_offset, addr, | ||
1789 | - bind_ack->dl_addr_length); | ||
1790 | - return 0; | ||
1791 | + dl_bind_req_t *bind_req = (dl_bind_req_t *) ctl_area; | ||
1792 | + dl_bind_ack_t *bind_ack = (dl_bind_ack_t *) ctl_area; | ||
1793 | + | ||
1794 | + bind_req->dl_primitive = DL_BIND_REQ; | ||
1795 | + bind_req->dl_sap = sap; | ||
1796 | + bind_req->dl_max_conind = 1; | ||
1797 | + bind_req->dl_service_mode = DL_CLDLS; | ||
1798 | + bind_req->dl_conn_mgmt = 0; | ||
1799 | + bind_req->dl_xidtest_flg = 0; | ||
1800 | + put_ctrl(fd, sizeof(dl_bind_req_t), 0); | ||
1801 | + get_msg(fd); | ||
1802 | + if(GOT_ERR == check_ctrl(DL_BIND_ACK)) { | ||
1803 | + printf(_ | ||
1804 | + ("Error: DLPI stream API failed to get MAC in dl_bind/check_ctrl(): %s.\n"), | ||
1805 | + strerror(errno)); | ||
1806 | + exit(STATE_UNKNOWN); | ||
1807 | + } | ||
1808 | + memcpy(addr, (u_char *) bind_ack + bind_ack->dl_addr_offset, | ||
1809 | + bind_ack->dl_addr_length); | ||
1810 | + return 0; | ||
1811 | } | ||
1812 | |||
1813 | + | ||
1814 | /*********************************************************************** | ||
1815 | * interface: | ||
1816 | * function mac_addr_dlpi - get the mac address of the interface with | ||
1817 | @@ -1197,37 +1229,39 @@ | ||
1818 | * | ||
1819 | * return: 0 if OK, -1 if the address could not be determined | ||
1820 | * | ||
1821 | - * | ||
1822 | ***********************************************************************/ | ||
1823 | |||
1824 | -long mac_addr_dlpi( const char *dev, int unit, u_char *addr) { | ||
1825 | +long | ||
1826 | +mac_addr_dlpi(const char *dev, int unit, u_char * addr) | ||
1827 | +{ | ||
1828 | |||
1829 | int fd; | ||
1830 | u_char mac_addr[25]; | ||
1831 | |||
1832 | - if (GOT_ERR != dl_open(dev, unit, &fd)) { | ||
1833 | - if (GOT_ERR != dl_bind(fd, INSAP, mac_addr)) { | ||
1834 | - bcopy( mac_addr, addr, 6); | ||
1835 | - return 0; | ||
1836 | - } | ||
1837 | + if(GOT_ERR != dl_open(dev, unit, &fd)) { | ||
1838 | + if(GOT_ERR != dl_bind(fd, INSAP, mac_addr)) { | ||
1839 | + memcpy(addr, mac_addr, 6); | ||
1840 | + return 0; | ||
1841 | + } | ||
1842 | } | ||
1843 | - close(fd); | ||
1844 | + close(fd); | ||
1845 | return -1; | ||
1846 | } | ||
1847 | |||
1848 | /* Kompf 2000-2003 */ | ||
1849 | - | ||
1850 | #endif | ||
1851 | |||
1852 | |||
1853 | /* print usage help */ | ||
1854 | -void print_help(void){ | ||
1855 | +void | ||
1856 | +print_help(void) | ||
1857 | +{ | ||
1858 | |||
1859 | - print_revision(progname,revision); | ||
1860 | + print_revision(progname, revision); | ||
1861 | |||
1862 | printf("Copyright (c) 2001-2004 Ethan Galstad (nagios@nagios.org)\n\n"); | ||
1863 | - printf (COPYRIGHT, copyright, email); | ||
1864 | - | ||
1865 | + printf(COPYRIGHT, copyright, email); | ||
1866 | + | ||
1867 | printf(_("This plugin tests the availability of DHCP servers on a network.\n\n")); | ||
1868 | |||
1869 | print_usage(); | ||
1870 | @@ -1241,6 +1275,8 @@ | ||
1871 | Seconds to wait for DHCPOFFER before timeout occurs\n\ | ||
1872 | -i, --interface=STRING\n\ | ||
1873 | Interface to to use for listening (i.e. eth0)\n\ | ||
1874 | + -u, --unicast=INTEGER\n\ | ||
1875 | + Unicast testing. Requires -s. Useful for testing servers on remote networks. | ||
1876 | -v, --verbose\n\ | ||
1877 | Print extra information (command-line use only)\n\ | ||
1878 | -h, --help\n\ | ||
1879 | @@ -1250,12 +1286,10 @@ | ||
1880 | } | ||
1881 | |||
1882 | |||
1883 | -void print_usage(void) | ||
1884 | +void | ||
1885 | +print_usage(void) | ||
1886 | { | ||
1887 | printf("\ | ||
1888 | Usage: %s [-s serverip] [-r requestedip] [-t timeout] [-i interface]\n\ | ||
1889 | - [-v]",progname); | ||
1890 | + [-v]", progname); | ||
1891 | } | ||
1892 | - | ||
1893 | - | ||
1894 | - | ||